我添加了这样的自定义授权方案......
public class AuthHandler : AuthenticationHandler<AuthOptions>
{
private readonly IUserIdentifierProvider userIdentifierProvider;
public AuthHandler(IUserIdentifierProvider userIdentifierProvider, IOptionsMonitor<AuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) :
base(options, logger, encoder, clock)
{
this.userIdentifierProvider = userIdentifierProvider;
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync() {
var ticket = ...
return Task.FromResult(AuthenticateResult.Success(ticket));
}
}
public static class AuthMiddlewareAppBuilderExtensions
{
public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder, Action<AuthOptions> configureOptions)
{
return builder.AddScheme<AuthOptions, AuthHandler>("Custom Scheme", "Custom Auth", configureOptions);
}
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddMemoryCache();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "Custom Scheme";
options.DefaultChallengeScheme = "Custom Auth";
})
.AddCustomAuth(o => {});
services.AddDbContext<DomainDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
});
var serviceProvider = ConfigureUnity(services);
return serviceProvider;
}
当MVC根据请求创建AuthHandler类时,它不使用从ConfigureServices返回的依赖注入容器。
我得到例外......
InvalidOperationException:无法解析类型的服务 尝试时'Web.Auth.Abstract.IUserIdentifierProvider' 激活'AuthHandler'。
为什么不使用我的容器?
如果我这样做的话......
services.AddTransient<IUserIdentifierProvider, UserIdentifierProvider>();
在ConfigureServices中。它似乎根本没有在我的容器中查找。那么它到底是从哪个地方获取实例的呢?它必须保持对传递给ConfigureServices的IServiceCollection的引用,并使用它而不是它应该的那个。
使用Reflector查看,ConfigureServices方法由以下函数调用...
public static StartupMethods LoadMethods(IServiceProvider hostingServiceProvider, Type startupType, string environmentName)
{
ConfigureBuilder builder = FindConfigureDelegate(startupType, environmentName);
ConfigureServicesBuilder builder2 = FindConfigureServicesDelegate(startupType, environmentName);
ConfigureContainerBuilder configureContainerMethod = FindConfigureContainerDelegate(startupType, environmentName);
object instance = null;
if (!builder.MethodInfo.get_IsStatic() || ((builder2 != null) && !builder2.MethodInfo.get_IsStatic()))
{
instance = ActivatorUtilities.GetServiceOrCreateInstance(hostingServiceProvider, startupType);
}
Func<IServiceCollection, IServiceProvider> configureServicesCallback = builder2.Build(instance);
Action<object> configureContainerCallback = configureContainerMethod.Build(instance);
return new StartupMethods(instance, builder.Build(instance), delegate (IServiceCollection services) {
IServiceProvider provider = configureServicesCallback(services);
if (provider != null)
{
return provider;
}
if (configureContainerMethod.MethodInfo != null)
{
Type[] typeArray1 = new Type[] { configureContainerMethod.GetContainerType() };
Type serviceType = typeof(IServiceProviderFactory<>).MakeGenericType(typeArray1);
object requiredService = hostingServiceProvider.GetRequiredService(serviceType);
object[] objArray1 = new object[] { services };
object obj3 = serviceType.GetMethod("CreateBuilder").Invoke(requiredService, objArray1);
configureContainerCallback(obj3);
object[] objArray2 = new object[] { obj3 };
provider = (IServiceProvider) serviceType.GetMethod("CreateServiceProvider").Invoke(requiredService, objArray2);
}
else
{
provider = hostingServiceProvider.GetRequiredService<IServiceProviderFactory<IServiceCollection>>().CreateServiceProvider(services);
}
return provider ?? services.BuildServiceProvider();
});
}
如果退回提供者,则已完成。
这没有任何意义。
答案 0 :(得分:0)
我在auth处理程序构造函数中对依赖项进行了硬编码。
简单,嗯?