我一直在玩IdentityServer3,希望替换我们当前的身份验证过程。当前,我们使用代码第一实体框架使用自定义身份框架过程。我设法安装了IdentityServer3,并使"内存"内容正常工作。现在,我想将其连接到我们已经定制的UserProvider
(如果愿意的话,UserManager
)。
我们已经使用了AUTOFAC,并将UserProvider
注册为这样:
builder.RegisterType<UserProvider>().As<IUserProvider>().InstancePerDependency();
我发现了一些文档,这些文档指出IdentityServer使用AutoFac本身。他们建议创建一个工厂,然后使用IdentityServerOptions
这样的用户服务:
options.Factory.UserService = new Registration<IUserService>(UserServiceFactory.Create())
我遇到的问题是工厂看起来像这样:
public class UserServiceFactory
{
public static AspNetIdentityUserService<User, string> Create()
{
var context = new IdentityDbContext();
var userStore = new UserStore<User>(context);
var userManager = new UserManager<User>(userStore);
return new AspNetIdentityUserService<User, string>(userManager);
}
}
使用常规 USERMANAGER 而不是我们的自定义版本和它不使用DI,因为您可以在静态方法中创建它。当然,最好使用AUTOFAC,因为我们已经拥有已注册的 userProvider 。因此,我没有使用他们的 IdentityServeroptions 来调用静态方法。所以我将工厂更改为此:
public class IdentityServerUserService : UserServiceBase
{
private readonly IUserProvider _userProvider;
public IdentityServerUserService(IUserProvider userProvider)
{
_userProvider = userProvider;
}
public override async Task AuthenticateLocalAsync(LocalAuthenticationContext context)
{
var user = await _userProvider.FindAsync(context.UserName, context.Password);
if (user != null && !user.Disabled)
{
// Get the UserClaims
// Add the user to our context
context.AuthenticateResult = new AuthenticateResult(user.Id, user.UserName, new List<Claim>());
}
}
}
我在AutoFac上注册的:
builder.RegisterType<IdentityServerUserService>()
.As<IdentityServer3.Core.Services.IUserService>()
.InstancePerDependency();
然后我分配给IdentityServerOptions.Factory.UserService
:
private static void SetupServices(IdentityServerOptions options, ILifetimeScope scope)
{
options.Factory.UserService = new Registration<IUserService>(scope.Resolve<IdentityServerUserService>());
}
和我得到的范围:
var config = new HttpConfiguration();
var scope = config.DependencyResolver.GetRootLifetimeScope();
我相信这应该可以起作用,但是当我尝试使用Postman进行身份验证时,我会遇到错误:
autofac.core.registration.com ponentnotregisteredException:请求的服务" butiness.IdentityServeruserService"尚未注册。为了避免此例外,要么注册一个组件以提供服务,要使用iSregistered()检查服务注册,或使用ResolveOptional()方法来解决可选的依赖性。
我尝试从InstancePerDependency
更改为InstancePerLifetimeScope
,但仍然有相同的错误。
所以,我有几个问题:
- 这是分配用户服务的正确方法?
- 这将允许我现有的用户进行身份验证?
- 以前有人做过吗?如果是这样,他们是否可以工作?
如果有人可以帮助我解决这些问题,我将永远感激不尽。
您可以解决IdentityServerUserService
,但您将IdentityServerUserService
注册为IUserService
。AUTOFAC不会自动将类型注册为本身。
要解决错误,您可以将类型注册为本身
builder.RegisterType<IdentityServerUserService>()
.As<IdentityServer3.Core.Services.IUserService>()
.InstancePerDependency();
或解决IUserService
options.Factory.UserService = new Registration<IUserService>(scope.Resolve<IUserService>())