现有项目

时间:2017-09-07 12:40:22

标签: c# asp.net-web-api asp.net-identity autofac identityserver3

我一直在玩IdentityServer3,希望能够取代我们当前的身份验证流程。 目前,我们使用代码第一实体框架的自定义身份框架流程。 我设法安装了IdentityServer3并在内存中获得了#34;"工作的东西。现在,我想将其与我们已定制的UserProviderUserManager,如果您愿意)联系起来。

我们已经使用Autofac并让我们的UserProvider注册如下:

builder.RegisterType<UserProvider>().As<IUserProvider>().InstancePerDependency();

我找到了一些说明IdentityServer uses 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(); 

我相信这应该有效,但当我尝试使用邮递员进行身份验证时,我收到错误:

  

Autofac.Core.Registration.ComponentNotRegisteredException:请求的服务&#39; Business.IdentityServerUserService&#39;尚未注册。要避免此异常,请注册组件以提供服务,使用IsRegistered()检查服务注册,或使用ResolveOptional()方法解析可选依赖项。

我尝试从InstancePerDependency更改为InstancePerLifetimeScope,但仍然遇到同样的错误。

所以,我有几个问题:

  • 这是分配UserService的正确方法吗?
  • 这是否允许我的现有用户进行身份验证?
  • 以前有人这样做过吗?如果是这样,他们是否让它发挥作用?

如果有人能帮助我解决这些问题,我将永远感激不尽。

1 个答案:

答案 0 :(得分:1)

您解决IdentityServerUserService,但注册IdentityServerUserServiceIUserService。 Autofac不会自动将类型注册为自身。

要修复错误,您可以将类型注册为

builder.RegisterType<IdentityServerUserService>()
       .As<IdentityServer3.Core.Services.IUserService>()
       .InstancePerDependency();

或解决IUserService

options.Factory.UserService = new Registration<IUserService>(scope.Resolve<IUserService>())