如何从 identityServer4 的现有数据库中获取用户

Posted

技术标签:

【中文标题】如何从 identityServer4 的现有数据库中获取用户【英文标题】:How to get users from a existing database for identityServer4 【发布时间】:2017-10-14 10:46:33 【问题描述】:

我试图了解如何将存储在现有数据库(位于:localhost:3306)中的用户(电子邮件、密码、名字、姓氏和操作系统)绑定到我的 identityserver4 项目中,以便我可以使用这些信息来登录用户或注册新用户到该数据库?

我阅读了一些教程(特别是 http://docs.identityserver.io/en/release/quickstarts/8_entity_framework.html),但我认为这始终适用于同一个项目中的 db。我的数据库不在同一个项目中。

在这种情况下,我阅读了有关 asp.net-core Identity 的信息。但我不完全理解这有什么关系。

谁能告诉我如何在我的项目中绑定数据库以及身份与应用程序用户等的作用是什么?

提前致谢

【问题讨论】:

实现某种用户存储,例如此处的 Teat 存储,但将其指向您的外部数据库。 github.com/IdentityServer/IdentityServer4.Samples/blob/release/Quickstarts/8_EntityFrameworkStorage/src/QuickstartIdentityServer/Quickstart/Account/AccountController.cs 【参考方案1】:

这篇文章更适合你的情况。您链接的是配置数据而不是用户数据: http://docs.identityserver.io/en/release/quickstarts/6_aspnet_identity.html

简而言之,您希望通过 Asp.Net Core Identity 访问您的用户数据。 您需要:

创建一个包含相关字段的用户类作为您的数据库 创建一个 EntityFramework DbContext 类以将您的数据库映射到您的类 使用 aspnet 核心身份注册您的用户类和 dbcontext 告诉 IdentityServer 使用 AspNetIdentity

这就是您的 Startup ConfigureServices 方法实施后的样子。此处未显示的是您需要创建的 DbContext 和 User 类。

public void ConfigureServices(IServiceCollection services)

    // Add framework services.
    services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<YourUserStoreDbContextHere>(options =>
            options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

    services.AddIdentity<YourUserClassHere, YourRoleClassHereIfAny>()
        .AddEntityFrameworkStores<YourUserStoreDbContextHere>()
        .AddDefaultTokenProviders();

    services.AddIdentityServer()
        // Other config here
        .AddAspNetIdentity<YourUserClassHere>();

有关配置用户类和 dbcontext 的详细信息,请参阅 AspNet Identity 上的文档:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity

【讨论】:

嗨,你给黑暗带来了很多光明。我有一个关于 User 类的问题。没有身份我有一个类用户(如表的名称),在这个类中我定义了用户的所有详细信息(如电子邮件、街道、性别..)如果我使用身份,我有一个继承自 IdentityUser 的 ApplicationUser 类。这和没有身份的用户是同一类吗?在这里我必须添加不属于 IdentityUser 的特殊信息(如性别)?我希望你能明白我的意思。【参考方案2】:

你需要实现自己的UserStore (example)

public async Task<TapkeyUser> ValidateCredentialsAsync(string username, string password)

      //This is pseudo-code implement your DB logic here
      if (database.query("select id from users where username = username and password = password") 
      
           return new User(); //return User from Database here 
       else 
           return null;
              

并在您的AccountController 中使用它:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginInputModel model)
    
        if (ModelState.IsValid)
        
            // use our custom UserStore here
 -------->  if (_users.ValidateCredentials(model.Username, model.Password))
            
                AuthenticationProperties props = null;
                // only set explicit expiration here if persistent. 
                // otherwise we reply upon expiration configured in cookie middleware.
                if (AccountOptions.AllowRememberLogin && model.RememberLogin)
                
                    props = new AuthenticationProperties
                    
                        IsPersistent = true,
                        ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)
                    ;
                ;

                // issue authentication cookie with subject ID and username
                var user = _users.FindByUsername(model.Username);
                await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username));
                await HttpContext.Authentication.SignInAsync(user.SubjectId, user.Username, props);

                // make sure the returnUrl is still valid, and if yes - redirect back to authorize endpoint or a local page
                if (_interaction.IsValidReturnUrl(model.ReturnUrl) || Url.IsLocalUrl(model.ReturnUrl))
                
                    return Redirect(model.ReturnUrl);
                

                return Redirect("~/");
            

            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials"));

            ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage);
        

        // something went wrong, show form with error
        var vm = await _account.BuildLoginViewModelAsync(model);
        return View(vm);
    

【讨论】:

以上是关于如何从 identityServer4 的现有数据库中获取用户的主要内容,如果未能解决你的问题,请参考以下文章

IdentityServer4 - 如何从另一个 ApiResource 调用一个 ApiResource

如何在 identityserver4 中没有用户名和密码的情况下从令牌端点获取令牌?

如果用户从 IdentityServer4 中的另一个浏览器/设备登录,如何检测并从应用程序中注销用户?

IdentityServer4学习记录

如何通过自省验证 IdentityServer4 访问令牌

如何使用 Asp.Net Core 2.2 / IdentityServer4 / SP.NET Core Identity 手动散列密码