asp.net-core - 关于 ASP.NET Core 3 Identity/Identity Server/SPA 支持资源所有者密码授予类型的问题

标签 asp.net-core identityserver4 asp.net-core-3.0 asp.net-core-identity

根据 Authentication and authorization for SPAs ,我创建了一个支持 API 授权的新 SPA。您可以 view this on GitHub .

为了支持集成测试,我添加了一个允许资源所有者密码授予类型的新客户端(请参阅 appsettings.json ):

"SecureSpa.IntegrationTests": {
  "Profile": "IdentityServerSPA",
  "AllowedGrantTypes": [ "password" ],
  "ClientSecrets": [ { "Value": "K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=" } ],
  "AllowedScopes": [ "SecureSpaAPI", "openid", "profile" ]
}

然后在WeatherForecastControllerTests.cs内,我尝试按如下方式请求 token :

var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
    Address = disco.TokenEndpoint,
    ClientId = "SecureSpa.IntegrationTests",
    ClientSecret = "secret",

    Scope = "SecureSpaAPI openid profile",
    UserName = "demouser@securespa",
    Password = "Pass@word1"
  });

运行测试时,我尝试了许多不同的组合,但结果通常相同( unauthorized_client )。这是 Identity Server 的相关日志输出:
IdentityServer4.Endpoints.TokenEndpoint: Debug: Start token request.
IdentityServer4.Validation.ClientSecretValidator: Debug: Start client validation
IdentityServer4.Validation.BasicAuthenticationSecretParser: Debug: Start parsing Basic Authentication secret
IdentityServer4.Validation.PostBodySecretParser: Debug: Start parsing for secret in post body
IdentityServer4.Validation.SecretParser: Debug: Parser found secret: PostBodySecretParser
IdentityServer4.Validation.SecretParser: Debug: Secret id found: SecureSpa.IntegrationTests
IdentityServer4.Stores.ValidatingClientStore: Debug: client configuration validation for client SecureSpa.IntegrationTests succeeded.
IdentityServer4.Validation.ClientSecretValidator: Debug: Public Client - skipping secret validation success
IdentityServer4.Validation.ClientSecretValidator: Debug: Client validation success
IdentityServer4.Events.DefaultEventService: Information: {
  "Name": "Client Authentication Success",
  "Category": "Authentication",
  "EventType": "Success",
  "Id": 1010,
  "ClientId": "SecureSpa.IntegrationTests",
  "AuthenticationMethod": "SharedSecret",
  "ActivityId": "0HLPN4PPDDMCJ",
  "TimeStamp": "2019-09-12T02:10:57Z",
  "ProcessId": 28948,
  "LocalIpAddress": "unknown",
  "RemoteIpAddress": "unknown"
}
IdentityServer4.Validation.TokenRequestValidator: Debug: Start token request validation
IdentityServer4.Validation.TokenRequestValidator: Debug: Start resource owner password token request validation
IdentityServer4.Validation.TokenRequestValidator: Error: Client not authorized for resource owner flow, check the AllowedGrantTypes setting{ client_id = SecureSpa.IntegrationTests }, details: {
  "ClientId": "SecureSpa.IntegrationTests",
  "ClientName": "SecureSpa.IntegrationTests",
  "GrantType": "password",
  "Raw": {
    "grant_type": "password",
    "username": "demouser@securespa",
    "password": "***REDACTED***",
    "scope": "SecureSpaAPI",
    "client_id": "SecureSpa.IntegrationTests",
    "client_secret": "***REDACTED***"
  }
}
IdentityServer4.Events.DefaultEventService: Information: {
  "Name": "Token Issued Failure",
  "Category": "Token",
  "EventType": "Failure",
  "Id": 2001,
  "ClientId": "SecureSpa.IntegrationTests",
  "ClientName": "SecureSpa.IntegrationTests",
  "Endpoint": "Token",
  "GrantType": "password",
  "Error": "unauthorized_client",
  "ActivityId": "0HLPN4PPDDMCJ",
  "TimeStamp": "2019-09-12T02:10:57Z",
  "ProcessId": 28948,
  "LocalIpAddress": "unknown",
  "RemoteIpAddress": "unknown"
}
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 212.96790000000001ms 400 application/json; charset=UTF-8

是否支持这种方法?如果没有,是否有替代方法可用于获取 token 以编写集成测试?我计划设置测试用户和测试客户端,以便我可以测试许多不同的行为。

最佳答案

我继续解决这个问题,发现当配置文件设置为 IdentityServerSPA 时,没有添加允许的密码授予类型。我看不到通过 appsettings 添加没有配置文件的客户端的方法,所以我从 appsettings 中删除了配置并使用这种方法创建了客户端:

services.AddIdentityServer()
    //.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
    {
        options.Clients.AddIdentityServerSPA("SecureSpa", builder =>
        {
            builder.WithRedirectUri("https://localhost:44307/authentication/login-callback");
            builder.WithLogoutRedirectUri("https://localhost:44307/authentication/logout-callback");
        });
        options.Clients.Add(new Client
        {
            ClientId = "SecureSpa.IntegrationTests",
            AllowedGrantTypes = { GrantType.ResourceOwnerPassword },
            ClientSecrets = { new Secret("secret".Sha256()) },
            AllowedScopes = { "SecureSpaAPI", "openid", "profile" }
        });
    });

有了这个,我的测试现在可以运行了。你可以在这里看到最终的解决方案; https://github.com/JasonGT/SecureSpa/ .

一切正常,但在 DefaultClientRequestParametersProvider 中似乎存在错误(或功能限制) .请参阅“GetClientParameters”方法 - 如果指定的客户端没有关联的配置文件,则 InvalidOperationException被抛出。

如果您需要更多信息,请与我们联系。

关于asp.net-core - 关于 ASP.NET Core 3 Identity/Identity Server/SPA 支持资源所有者密码授予类型的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57899926/

相关文章:

c# - project.json 解决方案项目引用

identityserver4 - 从.NET Core 2.2迁移到3.0后缺少AddJsonFormatters()

ssl - Identity Server 中缺少相互 TLS 引用

sql-server - 具有 Azure SQL 托管标识的 Entity Framework Core 导致用户“NT AUTHORITY\ANONYMOUS LOGON 登录失败”

azure - Asp.NET Core 2.1 HostedService - 继续在 Azure 上运行

c# - 通过依赖注入(inject)将配置传递给 webjobs

azure - 在azure应用程序服务部署中推送单个文件更改

c# - 在asp net core 3.1中使用RouteDataRequestCultureProvider

c# - 自定义 AuthenticationHandler 在 Asp.Net Core 3 中不起作用