由于authenticated_client错误而无法获取令牌

Kon*_*ten 3 c# token access-token asp.net-core identityserver4

我正在撰写有关如何使用Postman从IDS4获取令牌的演示。

密码令牌的请求来自IDS4的页面

[HttpGet("token")]
public IActionResult GetToken([FromHeader] string user, [FromHeader] string pass)
{
  string tokenEndpoint = "https://localhost:44300/connect/token";
  HttpClient client = new HttpClient();

  Task<TokenResponse> tokenResponse = 
    client.RequestPasswordTokenAsync(new PasswordTokenRequest
  {
    Address = tokenEndpoint,

    ClientId = "client",
    ClientSecret = "client_secret",
    Scope = "MemberApi.full",

    UserName = user,
    Password = pass
  });
  TokenResponse toko = tokenResponse.Result;

  if (toko.IsError)
    return Ok(toko.Error);
  return Ok(toko.AccessToken;
}
Run Code Online (Sandbox Code Playgroud)

客户端设置如下。

private static IEnumerable<Client> GetClients => new[]
{
  ...
  new Client
  {
    ClientId = "client",
    ClientSecrets = { new Secret("client_secret".Sha256()) },
    ClientName = "Client",

    AllowedGrantTypes = GrantTypes.Implicit,
    AllowAccessTokensViaBrowser = true,

    RedirectUris = { "http://localhost:5000/security/credentials" },
    PostLogoutRedirectUris = { "http://localhost:5000/index.html" },
    AllowedCorsOrigins = { "http://localhost:5000", "https://localhost:44300" },

    AllowedScopes =
    {
      IdentityServerConstants.StandardScopes.OpenId,
      IdentityServerConstants.StandardScopes.Profile,
      IdentityServerConstants.StandardScopes.Email,
      "MemberApi",
      "MemberApi.full",
      "MemberApi.limited"
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

API资源的设置如下所示。

private static IEnumerable<ApiResource> GetApis => new[]
{
  new ApiResource
  {
    Name = "MemberApi",
    DisplayName = "Members' API",
    ApiSecrets = {new Secret("MemberSecret".Sha256())},
    UserClaims = {JwtClaimTypes.Name, JwtClaimTypes.Email, JwtClaimTypes.Role},
    Scopes = {new Scope("MemberApi.full"), new Scope("MemberApi.limited")}
  }
};
Run Code Online (Sandbox Code Playgroud)

据我所知,我遵循了文档中的建议。我也尝试与示例进行比较。尽管如此,我仍然停留在错误消息上,名为username_client。我会缺少什么?

Rua*_*urg 6

此流程不允许客户请求:

AllowedGrantTypes = GrantTypes.Implicit
Run Code Online (Sandbox Code Playgroud)

忘记client.RequestPasswordTokenAsync。您不需要它,也无法使用它。在隐式流程中,只有用户知道密码。对于客户来说这是遥不可及的。

假设IdentityServer在一个域上运行:https//idp.mydomain.com,而客户端在其他域上运行:https//mvc.mydomain.com

当用户在mvc客户端上单击安全页面时,该用户将被路由到用户登录的IdentityServer。在该用户中输入凭据,如果成功,则将用户作为已知身份返回到客户端。

取决于流,客户端最终最终会获得至少一个访问令牌。该令牌很重要,因为它允许客户端代表用户访问资源。这就像一张入场券。

现在,根据访问令牌,资源知道WHO想要访问该资源。访问令牌有一个区分这一点的声明,即“子”声明。没有此声明,客户端将无法访问此流程中的资源。

在您的配置中,允许客户端访问“ MemberApi”作用域,但在实际访问资源之前,需要用户的同意。


如果要从最简单的流程开始检索令牌,则客户端凭据流程。

那就是根本没有用户的流程。客户端(如在软件中)可以使用clientid + secret登录。如果配置正确,将产生访问令牌。

现在,客户端无需任何用户交互即可访问资源。身份令牌不可用,因为没有用户。缺少“子”要求。此流中不支持刷新令牌,不需要它。客户端可以使用凭据请求新令牌。


如果您想知道刷新令牌是如何工作的,则在混合流中,用户将登录并另外(如果配置了scope = offline)将返回刷新令牌。

由于访问令牌仅在短时间内有效(取决于到期时间),因此必须获取新令牌。为此,应使用刷新令牌。刷新令牌允许客户端请求新的访问令牌,而无需用户交互(脱机访问)。

使用新的访问令牌,直到它过期,并且必须请求一个新的令牌。直到刷新令牌本身到期为止,但是可以对其进行配置。


隐式流中,没有刷新令牌,但是访问令牌确实全部过期。因此,您将需要另一种刷新令牌的方法。为此,您可以使用无提示令牌续订实现。

有关术语,请阅读文档

请注意各种流程。这完全取决于环境。是否有用户,是否是浏览器应用程序,是否存在前通道,后通道,是否需要脱机访问,客户端可以保密吗?选择流之前需要考虑的事情。

选择流后,您需要为客户端配置允许的授予。如果仅允许隐式授予类型,则使用客户端凭据的客户端无法访问资源。

IdentityServer主要用于配置客户端和资源。查看示例以查看不同的流以及如何配置它们。