Перевод ninject Обязательная привязка ISecureDataFormat к Autofac
Я переношу большую базу кода из Ninject в Autofac и борюсь за одно из привязок (что, по моему мнению, вызывает ошибку активации на основе некоторой моей отладки).
Ninject:
Bind<ISecureDataFormat<AuthenticationTicket>>()
.ToMethod(context =>
{
var owinContext = context.Kernel.Get<IOwinContext>();
return owinContext
.Get<ISecureDataFormat<AuthenticationTicket>>("SecureDataFormat");
});
Autofac (что у меня есть):
builder.Register(
context => context.Resolve<IOwinContext>()
.Get<ISecureDataFormat<AuthenticationTicket>>("SecureDataFormat"))
.As<ISecureDataFormat<AuthenticationTicket>>();
Startup.cs:
var container = RegisterIoC(app, config);
public IContainer RegisterIoC(IAppBuilder app, HttpConfiguration config)
{
var builder = new ContainerBuilder();
builder = RegisterDependencies(builder);
builder = RegisterFilters(builder, config);
/*builder.RegisterModule<DebuggingRequestModule>();*/
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
app.UseAutofacMiddleware(container);
app.UseAutofacMvc();
app.UseAutofacWebApi(config);
app.UseWebApi(config);
return container;
}
Больше:
builder.RegisterModule<ApiDependencyModule>().RegisterModule<AutofacWebTypesModule>();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterApiControllers(typeof(AccountController).Assembly);
(по-видимому) связанных конструкторов:
AccountController.cs:
public AccountController(ILoginService loginService,
IBearerTokenStore tokenStore,
IRememberMeCookieService rememberMeCookieService,
IInternalSsoChallenge ssoChallenge)
{
LoginService.cs:
public LoginService(IBearerTokenStore tokenStore,
IGrantTypeProvider grantProvider,
IRememberMeCookieService rememberMeCookieService)
{
BearerTokenCookieStore.cs:
public BearerTokenCookieStore(IOwinContext owinContext, ISecureDataFormat<AuthenticationTicket> secureDataFormat, IAppSettingsReader appSettingsReader, ICookieService cookieService)
{
У меня есть модуль регистрации, который помогает мне отлаживать, и это список сообщений, которые у меня есть.
Resolving _______.Login.Controllers.AccountController
--Resolving _______.ApiGateway.Services.Auth.LoginService
----Resolving _______.ApiGateway.Security.OAuth.BearerTokenCookieStore
------Resolving Microsoft.Owin.Security.DataHandler.SecureDataFormat'1[Microsoft.Owin.Security.AuthenticationTicket]
Exception thrown: 'Autofac.Core.DependencyResolutionException' in Autofac.dll
Exception thrown: 'Autofac.Core.DependencyResolutionException' in Autofac.dll
Exception thrown: 'Autofac.Core.DependencyResolutionException' in Autofac.dll
The thread 0x1014 has exited with code 0 (0x0).
Редактировать:
Исключением я вижу:
An error occurred during the activation of a particular registration.
See the inner exception for details. Registration:
Activator = AccountController (DelegateActivator),
Services = [____.Login.Controllers.AccountController],
Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,
Sharing = None,
Ownership = ExternallyOwned --->
An error occurred during the activation of a particular registration.
See the inner exception for details.
Registration:
Activator = AccountController (ReflectionActivator),
Services = [____.Login.Controllers.AccountController],
Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,
Sharing = None, Ownership = OwnedByLifetimeScope ---> An error occurred during the activation of a particular registration.
See the inner exception for details.
Registration:
Activator = LoginService (DelegateActivator),
Services = [____.ApiGateway.Services.Auth.ILoginService],
Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,
Sharing = None,
Ownership = ExternallyOwned ---> An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = LoginService (ReflectionActivator),
Services = [____.ApiGateway.Services.Auth.ILoginService],
Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,
Sharing = None,
Ownership = OwnedByLifetimeScope ---> An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = BearerTokenCookieStore (DelegateActivator),
Services = [____.ApiGateway.Security.OAuth.IBearerTokenStore],
Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,
Sharing = None,
Ownership = ExternallyOwned ---> An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = BearerTokenCookieStore (ReflectionActivator),
Services = [____.ApiGateway.Security.OAuth.IBearerTokenStore],
Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,
Sharing = Shared,
Ownership = OwnedByLifetimeScope ---> An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = ISecureDataFormat'1 (DelegateActivator),
Services = [Microsoft.Owin.Security.ISecureDataFormat'1[[Microsoft.Owin.Security.AuthenticationTicket,
Microsoft.Owin.Security,
Version=3.0.1.0,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35]]],
Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,
Sharing = None,
Ownership = ExternallyOwned ---> An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = ISecureDataFormat'1 (DelegateActivator),
Services = [Microsoft.Owin.Security.ISecureDataFormat'1[[Microsoft.Owin.Security.AuthenticationTicket,
Microsoft.Owin.Security,
Version=3.0.1.0,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35]]],
Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,
Sharing = None,
Ownership = OwnedByLifetimeScope ---> A delegate registered to create instances of 'Microsoft.Owin.Security.ISecureDataFormat'1[Microsoft.Owin.Security.AuthenticationTicket]' returned null. (See inner exception for details.) (See inner exception for details.) (See inner exception for details.) (See inner exception for details.) (See inner exception for details.) (See inner exception for details.) (See inner exception for details.) (See inner exception for details.)
Внутреннее большинство:
A delegate registered to create instances of 'Microsoft.Owin.Security.ISecureDataFormat'1[Microsoft.Owin.Security.AuthenticationTicket]' returned null.
Ответы
Ответ 1
Мы можем использовать autofac с этими инверсиями контроля С# owin (от autofac), как показано ниже.
Startup.cs
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
ConfigureIoC(app, config);
Components.Config();
Auth.ConfigureForApi(app);
app.UseAutofacWebApi(config);
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(config);
config.EnsureInitialized();
}
private void ConfigureIoC(IAppBuilder app, HttpConfiguration config)
{
IoC.RegisterModules(
builder =>
{
builder.Register<IAuthenticationManager>(c => c.Resolve<IOwinContext>().Authentication).InstancePerRequest();
builder.Register<IDataProtectionProvider>(c => app.GetDataProtectionProvider()).InstancePerRequest();
builder.RegisterApiControllers(typeof(Startup).Assembly).PropertiesAutowired();
},
container =>
{
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
app.UseAutofacMiddleware(container);
},
true
);
}
}
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Конфигурация компонента:
public static class Components
{
public static void Config() {
TypeAdapterConfig.GlobalSettings.AllowImplicitDestinationInheritance = true;
var registers = new List<IRegister>();
registers.Add(new DtoMapping());
registers.Add(new MappingRegistration());
TypeAdapterConfig.GlobalSettings.Apply(registers);
ObjectMapper.Current = new MapsterAdapter();
DbConfiguration.Loaded += DbConfiguration_Loaded;
var r = new Registrations();
r.Run();
}
private static void DbConfiguration_Loaded(object sender, System.Data.Entity.Infrastructure.DependencyResolution.DbConfigurationLoadedEventArgs e)
{
e.ReplaceService<DbProviderServices>((s, k) => System.Data.Entity.SqlServer.SqlProviderServices.Instance);
}
}
Аутентификация:
public class Auth
{
public static void ConfigureForMvc(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, UserEntity, int>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentityCallback: (manager, user) =>
user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ApplicationCookie),
getUserIdCallback: (Identity) => Identity.GetUserId<int>())
}
});
}
public static void ConfigureForApi(IAppBuilder app)
{
var OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/oauth2/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(120),
Provider = new CustomOAuthProvider(),
AccessTokenFormat = new CustomJwtFormat(ConfigConstants.Issuer)
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] { ConfigConstants.AudienceId },
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(ConfigConstants.Issuer, ConfigConstants.AudienceSecurityKey)
}
});
}
}