C# 尝试将IdentityServer4添加为具有自定义用户存储的Javascript应用程序的身份授权
我按照文档使用默认的测试配置(内存中的客户端和用户)创建了一个基本的本地实现。此时,IS4初始化如下:C# 尝试将IdentityServer4添加为具有自定义用户存储的Javascript应用程序的身份授权,c#,asp.net,asp.net-core,identityserver4,oidc-client-js,C#,Asp.net,Asp.net Core,Identityserver4,Oidc Client Js,我按照文档使用默认的测试配置(内存中的客户端和用户)创建了一个基本的本地实现。此时,IS4初始化如下: services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryIdentityResources(Config.GetIdentityResources()) .AddInMemoryApiResources(Config.GetApiResources()) .AddInMe
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
然后,我介绍了如何使用该库创建一个简单的Javascript应用程序。这很好,所以现在我有了一个Javascript应用程序,它允许用户通过我的IS4实例登录。按照说明,这个JS应用程序在IS4中表示为使用隐式流的客户端
我现在想将我的IS4实例与我的real users商店集成。读了几篇文章后,我似乎需要提供IResourceOwnerPasswordValidator
和IProfileService
的实现,以及其他各种实现
我已经这样做了,现在只使用一个虚拟用户存储库,它与一组虚拟内存用户一起工作,而不是一个真正的外部存储。我的IS4初始化现在如下所示:
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());
builder.Services.AddTransient<IProfileService, CustomProfileService>();
builder.Services.AddTransient<IResourceOwnerPasswordValidator, CustomResourceOwnerPasswordValidator>();
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());
builder.Services.AddTransient();
builder.Services.AddTransient();
现在,当我回去测试我的Javascript应用程序时,这就是它变得奇怪的地方。当尝试登录时,我会进入我的IS4登录屏幕。我输入了预期工作的凭据,但返回了无效的用户名或密码。调试我可以看到代码从未进入CustomResourceOwnerPasswordValidator
中的ValidateSync
方法。然而,我偶然发现,如果我输入bob或alice作为用户名和密码(例如,输入bob作为用户名和密码),那么我已经通过身份验证,可以返回到我的应用程序。这没有任何意义。我确信这些用户名不是巧合,它们是IdentityServer4示例内存用户使用的两个默认用户,但是您可以看到上面我不再使用内存用户了。事实上,即使我在Config.cs
中注释GetUsers
方法,这仍然是正确的
我无法解释这一点,但无论如何,我想要的是能够使用我的用户商店。因此,我进一步阅读了一些建议,认为我只能对具有GrantTypes.ResourceOwnerPassword
的客户端使用IResourceOwnerPasswordValidator
。然而,当我在IS4中将Javascript应用程序的客户端更改为使用此授权类型时,当我尝试登录时,我看到一个未经授权的_客户端错误
所以我被卡住了。我曾认为,由于我的设置与内存中的用户一起工作,因此使用真正的用户存储不会有太多工作,但显然我缺少了一些东西。非常感谢您的指导。您不需要将您的
ProfileService
作为依赖项注入到您的服务中
你需要像这样的东西:
services.AddIdentityServer()
.AddProfileService<CustomProfileService>()
//..... more code
在那里,在
LoginInputModel
中,您有需要验证的用户名、密码等,因此如果您正在编写自定义用户管理,那么最后就不需要IProfileService
。如果第二段代码真的是您的IS4启动,我无法解释为什么“Bob”和“Alice”工作是因为您尚未连接任何配置文件服务——您需要添加一个.AddProfileService(CustomProfileService)
调用到您的AddIdentityServer
设置序列。您的虚拟用户存储看起来像什么?另外,您不需要注册IProfileService
进行注入,IS4不使用它,而且在编写IS4用户界面代码时,它对用户管理没有帮助。原来bob和alice在我使用的快速入门AccountController
中被用作测试用户。如果在代码库中快速搜索“alice”,就会发现这个问题,所以我看起来很愚蠢!非常感谢。我显然是找错人了!在你的帮助下,我现在可以工作了。这也解释了为什么我的bob和alice用户在工作——他们被设置为quick startAccountController
的测试帐户。
/// <summary>
/// Handle postback from username/password login
/// </summary>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginInputModel model)
{
// logic
}