代码之家  ›  专栏  ›  技术社区  ›  Tom Troughton

尝试将IdentityServer4添加为具有自定义用户存储的Javascript应用程序的标识权限

  •  0
  • Tom Troughton  · 技术社区  · 7 年前

    我跟踪了 IdentityServer4 使用默认测试配置(内存中的客户端和用户)创建基本本地实现的文档。此时,IS4初始化如下:

    services.AddIdentityServer()
        .AddDeveloperSigningCredential()
        .AddInMemoryIdentityResources(Config.GetIdentityResources())
        .AddInMemoryApiResources(Config.GetApiResources())
        .AddInMemoryClients(Config.GetClients())
        .AddTestUsers(Config.GetUsers());
    

    那我就 followed the instructions 用于使用 oidc-connect 图书馆这很好,所以现在我有了一个Javascript应用程序,允许用户通过我的IS4实例登录。按照说明,此JS应用程序在IS4中表示为使用隐式流的客户端。

    我现在想将我的IS4实例与我的real users商店集成。读了几篇文章之后,我似乎需要为 IResourceOwnerPasswordValidator IProfileService 根据 this SO post 以及其他各种类型。

    我已经做到了这一点,目前只使用了一个虚拟用户存储库,它可以处理一组虚拟内存用户,而不是一个真正的外部存储。我的IS4初始化现在如下所示:

    services.AddIdentityServer()
        .AddDeveloperSigningCredential()
        .AddInMemoryIdentityResources(Config.GetIdentityResources())
        .AddInMemoryApiResources(Config.GetApiResources())
        .AddInMemoryClients(Config.GetClients());
    
    builder.Services.AddTransient<IProfileService, CustomProfileService>();
    builder.Services.AddTransient<IResourceOwnerPasswordValidator, CustomResourceOwnerPasswordValidator>();
    

    现在,当我回去测试我的Javascript应用程序时,这就是它变得奇怪的地方。当尝试登录时,我会进入我的IS4登录屏幕。我输入了我希望工作的凭据,但是 用户名或密码无效 已返回。调试我可以看到代码从未进入 ValidateAsync 中的方法 CustomResourceOwnerPasswordValidator . 然而 ,碰巧我发现如果我输入 上下快速移动 爱丽丝 作为用户名和密码(例如,输入 上下快速移动 作为用户名 密码),然后我经过身份验证,可以返回到我的应用程序。这没有任何意义。我确信这些用户名不是巧合,它们是IdentityServer4示例内存用户使用的两个默认用户,但您可以看到上面我不再使用内存用户。事实上,即使在我评论 GetUsers 方法,共个 Config.cs .

    我无法解释这一点,但无论如何,我想要的是能够使用我的用户存储。所以我读了进一步的内容,看到了一些我只能使用的建议 IResourceOwnerPasswordValidator 与拥有 GrantTypes.ResourceOwnerPassword . 然而,当我在IS4中更改Javascript应用程序的客户端以使用此授予类型时,当我尝试登录时,我会看到 未经授权的\u客户端 错误

    所以我被困住了。我曾认为,由于我的设置与内存中的用户一起工作,那么使用真正的用户存储将不会有太多工作,但很明显,我缺少了一些东西。非常感谢您的指导。

    1 回复  |  直到 7 年前
        1
  •  1
  •   m3n7alsnak3    7 年前

    你不需要注射 ProfileService 作为服务中的依赖项。

    您需要以下内容:

    services.AddIdentityServer()
                .AddProfileService<CustomProfileService>()
                //..... more code
    

    此外,您的 CustomProfileService 不需要实施 IProfileService (该方法接受泛型)。

    真正的“魔法”发生在 AccountController 在中:

    /// <summary>
        /// Handle postback from username/password login
        /// </summary>
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Login(LoginInputModel model)
        {
            // logic
        }
    

    在那里,在 LoginInputModel 您有需要验证的用户名、密码等,因此最终不需要 IProfileService 如果您正在编写自定义用户管理。