appsettings.json 中的 ClientSecret 与 IdentityServer4

Chr*_*isO 6 asp.net-core identityserver4

我正在尝试让 IdentityServer4 使用 appsettings.json 指定混合授权类型的客户端密钥。

本文末尾说,如果我想将密钥放入 appsettings.json 中,我需要对其进行 sha256 哈希,然后对密钥进行 Base64 编码。因此,将秘密“秘密”放入https://emn178.github.io/online-tools/sha256.html中,得到“2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b”,其base64编码为“MmJiODBkNTM3YjFkYTNlMzhiZDM” wMzYxYWE4NTU2ODZiZGUwZWFjZDcxNjJmZWY2YTI1ZmU5N2JmNTI3YTI1Yg==”。这使得我的 mvc 客户端的 appsettings.json 看起来像这样

{
    ...
    "ClientSecrets": [ { 
        "Value": "MkJCODBENTM3QjFEQTNFMzhCRDMwMzYxQUE4NTU2ODZCREUwRUFDRDcxNjJGRUY2QTI1RkU5N0JGNTI3QTI1Qg=="
    } ],
    ...
}
Run Code Online (Sandbox Code Playgroud)

在 MVC 客户端上,配置如下所示

.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.Authority = Configuration["OpenIdConnectAuthority"];

    options.ClientId = "xxx-mvc";
    options.ClientSecret = "secret";

    options.RemoteAuthenticationTimeout = TimeSpan.FromHours(2);
    options.ResponseType = "code id_token";
    options.RequireHttpsMetadata = !Environment.IsDevelopment();
    options.Scope.Clear();
    options.Scope.Add("openid profile");

    options.CallbackPath = new PathString("/signin-callback-oidc");
    options.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
    options.SignedOutRedirectUri = new PathString("/");
    options.ClaimsIssuer = OpenIdConnectDefaults.AuthenticationScheme;

    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = JwtClaimTypes.Name
    };
})
Run Code Online (Sandbox Code Playgroud)

尽管这看起来是正确的,但身份服务器日志有

fail: IdentityServer4.Validation.ClientSecretValidator[0]
      Client secret validation failed for client: xxx-mvc.
Run Code Online (Sandbox Code Playgroud)

如果我删除 Base64 机密的一部分,身份服务器会记录

Secret: no description uses invalid hashing algorithm.

所以我知道 appsettings.json 客户端密钥正在被获取。options.ClientSecret = "secret";如果我在 mvc 端注释掉,身份服务器会记录日志Hashed shared secret validator cannot process NoSecret,这样我就知道配置正在被获取。

如何指定正确的两个字符串以使秘密“秘密”在这种情况下发挥作用?

来自身份服务器的完整日志是:

dbug: IdentityServer4.Hosting.EndpointRouter[0]
      Request path /.well-known/openid-configuration matched to endpoint type Discovery
dbug: IdentityServer4.Hosting.EndpointRouter[0]
      Endpoint enabled: Discovery, successfully created handler: IdentityServer4.Endpoints.DiscoveryEndpoint
info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking IdentityServer endpoint: IdentityServer4.Endpoints.DiscoveryEndpoint for /.well-known/openid-configuration
trce: IdentityServer4.Endpoints.DiscoveryEndpoint[0]
      Processing discovery request.
dbug: IdentityServer4.Endpoints.DiscoveryEndpoint[0]
      Start discovery request
trce: IdentityServer4.Endpoints.DiscoveryEndpoint[0]
      Calling into discovery response generator: IdentityServer4.ResponseHandling.DiscoveryResponseGenerator
trce: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking result: IdentityServer4.Endpoints.Results.DiscoveryDocumentResult
dbug: IdentityServer4.Hosting.EndpointRouter[0]
      Request path /.well-known/openid-configuration/jwks matched to endpoint type Discovery
dbug: IdentityServer4.Hosting.EndpointRouter[0]
      Endpoint enabled: Discovery, successfully created handler: IdentityServer4.Endpoints.DiscoveryKeyEndpoint
info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking IdentityServer endpoint: IdentityServer4.Endpoints.DiscoveryKeyEndpoint for /.well-known/openid-configuration/jwks
trce: IdentityServer4.Endpoints.DiscoveryKeyEndpoint[0]
      Processing discovery request.
dbug: IdentityServer4.Endpoints.DiscoveryKeyEndpoint[0]
      Start key discovery request
trce: IdentityServer4.Endpoints.DiscoveryKeyEndpoint[0]
      Calling into discovery response generator: IdentityServer4.ResponseHandling.DiscoveryResponseGenerator
trce: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking result: IdentityServer4.Endpoints.Results.JsonWebKeysResult
dbug: IdentityServer4.Hosting.EndpointRouter[0]
      Request path /connect/authorize matched to endpoint type Authorize
dbug: IdentityServer4.Hosting.EndpointRouter[0]
      Endpoint enabled: Authorize, successfully created handler: IdentityServer4.Endpoints.AuthorizeEndpoint
info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking IdentityServer endpoint: IdentityServer4.Endpoints.AuthorizeEndpoint for /connect/authorize
dbug: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
      Start authorize request
dbug: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
      User in authorize request: 3a28f734-5d49-49e0-a28c-c851adfb4bf6
dbug: IdentityServer4.Validation.AuthorizeRequestValidator[0]
      Start authorize request protocol validation
trce: IdentityServer4.Stores.ValidatingClientStore[0]
      Calling into client configuration validator: IdentityServer4.Validation.DefaultClientConfigurationValidator
dbug: IdentityServer4.Stores.ValidatingClientStore[0]
      client configuration validation for client xxx-mvc succeeded.
dbug: IdentityServer4.Validation.AuthorizeRequestValidator[0]
      Checking for PKCE parameters
dbug: IdentityServer4.Validation.AuthorizeRequestValidator[0]
      No PKCE used.
dbug: IdentityServer4.Validation.AuthorizeRequestValidator[0]
      Calling into custom validator: IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator
trce: IdentityServer4.Validation.AuthorizeRequestValidator[0]
      Authorize request protocol validation successful
dbug: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
      ValidatedAuthorizeRequest
      {
        "ClientId": "xxx-mvc",
        "ClientName": "xxx MVC Client",
        "RedirectUri": "http://localhost:4500/signin-callback-oidc",
        "AllowedRedirectUris": [
          "http://localhost:4500/signin-callback-oidc"
        ],
        "SubjectId": "3a28f734-5d49-49e0-a28c-c851adfb4bf6",
        "ResponseType": "code id_token",
        "ResponseMode": "form_post",
        "GrantType": "hybrid",
        "RequestedScopes": "openid profile",
        "State": "CfDJ8BvOOrOwFENEmcvniNGXxvPnb1gKLB_qQdpSkS5FI88I3vvopAgk9v23GYrBOce_S5PeDsBUzYEj28zpC__y1Q8ZcU2LE9vf7x9pBvmqltXBBdp4zRbhV52iiTEtfpj-MyvDrMTUWR1jCx_b4CmdObvZdVdqf3KvUKO6dCJvPVP5G0OBG6jkuWUvsQnm8uUTE28XBrhwMIn_3D1ns2BgShqtV6j9G7HzatthP-yg9tDV198xILScflYHAgNPWGiJUZcZoar1_FSi9ynxlJSonnkuAw6epwPYk1lvIKZrK5ofTHizmOBUHI_b-xyVXIzoQw",
        "Nonce": "637027688717360370.ODBiYTgwZGMtNjRhYy00NmE4LWI3MDAtYWY4MTcxMmNkMmNjYmYwYjY1ZDUtMTUyYy00YjFlLWE2ZmMtNTdkM2YzMDY3NTAy",
        "SessionId": "3b0abfecf91a43a58e3f24ccb6ff1351",
        "Raw": {
          "client_id": "xxx-mvc",
          "redirect_uri": "http://localhost:4500/signin-callback-oidc",
          "response_type": "code id_token",
          "scope": "openid profile",
          "response_mode": "form_post",
          "nonce": "637027688717360370.ODBiYTgwZGMtNjRhYy00NmE4LWI3MDAtYWY4MTcxMmNkMmNjYmYwYjY1ZDUtMTUyYy00YjFlLWE2ZmMtNTdkM2YzMDY3NTAy",
          "state": "CfDJ8BvOOrOwFENEmcvniNGXxvPnb1gKLB_qQdpSkS5FI88I3vvopAgk9v23GYrBOce_S5PeDsBUzYEj28zpC__y1Q8ZcU2LE9vf7x9pBvmqltXBBdp4zRbhV52iiTEtfpj-MyvDrMTUWR1jCx_b4CmdObvZdVdqf3KvUKO6dCJvPVP5G0OBG6jkuWUvsQnm8uUTE28XBrhwMIn_3D1ns2BgShqtV6j9G7HzatthP-yg9tDV198xILScflYHAgNPWGiJUZcZoar1_FSi9ynxlJSonnkuAw6epwPYk1lvIKZrK5ofTHizmOBUHI_b-xyVXIzoQw",
          "x-client-SKU": "ID_NETSTANDARD2_0",
          "x-client-ver": "5.3.0.0"
        }
      }
trce: IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator[0]
      ProcessInteractionAsync
dbug: IdentityServer4.Services.DefaultConsentService[0]
      Client is configured to not require consent, no consent is required
dbug: IdentityServer4.ResponseHandling.AuthorizeResponseGenerator[0]
      Creating Hybrid Flow response.
dbug: IdentityServer4.EntityFramework.Stores.PersistedGrantStore[0]
      GpVcH5oK1O8xEaWazwBmHumW8moTQsBnVATxPiUxIfs= not found in database
dbug: IdentityServer4.ResponseHandling.AuthorizeResponseGenerator[0]
      Creating Implicit Flow response.
trce: IdentityServer4.Services.DefaultTokenService[0]
      Creating identity token
dbug: IdentityServer4.Services.DefaultClaimsService[0]
      Getting claims for identity token for subject: 3a28f734-5d49-49e0-a28c-c851adfb4bf6 and client: xxx-mvc
dbug: IdentityServer4.Services.DefaultClaimsService[0]
      In addition to an id_token, an access_token was requested. No claims other than sub are included in the id_token. To obtain more user claims, either use the user info endpoint or set AlwaysIncludeUserClaimsInIdToken on the client configuration.
trce: IdentityServer4.Services.DefaultTokenService[0]
      Creating JWT identity token
trce: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
      Identity token issued for xxx-mvc (xxx MVC Client) / 3a28f734-5d49-49e0-a28c-c851adfb4bf6: eyJhbGciOiJSUzI1NiIsImtpZCI6Ijc3ODc1NWJmMmZkMWRiZWVmNjZkZDdmZjY2YmM5NjBlIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1NjcxNzIwNzEsImV4cCI6MTU2NzE3MjM3MSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo0NDAwIiwiYXVkIjoibW9uZXRlZXItbXZjIiwibm9uY2UiOiI2MzcwMjc2ODg3MTczNjAzNzAuT0RCaVlUZ3daR010TmpSaFl5MDBObUU0TFdJM01EQXRZV1k0TVRjeE1tTmtNbU5qWW1Zd1lqWTFaRFV0TVRVeVl5MDBZakZsTFdFMlptTXROVGRrTTJZek1EWTNOVEF5IiwiaWF0IjoxNTY3MTcyMDcxLCJjX2hhc2giOiJNR3A5SzlLSm5KRTFaZW83YndoNG5BIiwic2lkIjoiM2IwYWJmZWNmOTFhNDNhNThlM2YyNGNjYjZmZjEzNTEiLCJzdWIiOiIzYTI4ZjczNC01ZDQ5LTQ5ZTAtYTI4Yy1jODUxYWRmYjRiZjYiLCJhdXRoX3RpbWUiOjE1NjcxNjk2NTAsImlkcCI6ImxvY2FsIiwiYW1yIjpbInB3ZCJdfQ.p9LKUCqmK8fjlznJtU5NGgtKE2fsSnxx8EW2ngu2pw-eSJXsuvI7t6FkxlHw6joVG178JXGfMY4BXt83binl9li3NLjzjJC7k8_07QUL_fknYB05rwhfAH995mxqXTV1A5n8ppjXzXcixAkVaA1Cxgb7mvqqfVHqRY2ra-MeIa7Esew5CiTeerlMT87wdWbIMmbK84TGSM26jLN1Uav6YYB-8Lonu2hcS3s4LXLS42bvy04Uc-UUOXcxK0LDgQu-stWfFjr9tYeoIefsgZIOJaEDtgwulExhNWTrPlFF5k9qYyYv4keKM_1dckP47-B4TR5m_1PEzGNeSJb48RwrXQ
trce: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
      Code issued for xxx-mvc (xxx MVC Client) / 3a28f734-5d49-49e0-a28c-c851adfb4bf6: 05331f140cb9626a391f6033d1ab6396711b614cdab5f224024336aa94f996f4
dbug: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
      Authorize endpoint response
      {
        "SubjectId": "3a28f734-5d49-49e0-a28c-c851adfb4bf6",
        "ClientId": "xxx-mvc",
        "RedirectUri": "http://localhost:4500/signin-callback-oidc",
        "State": "CfDJ8BvOOrOwFENEmcvniNGXxvPnb1gKLB_qQdpSkS5FI88I3vvopAgk9v23GYrBOce_S5PeDsBUzYEj28zpC__y1Q8ZcU2LE9vf7x9pBvmqltXBBdp4zRbhV52iiTEtfpj-MyvDrMTUWR1jCx_b4CmdObvZdVdqf3KvUKO6dCJvPVP5G0OBG6jkuWUvsQnm8uUTE28XBrhwMIn_3D1ns2BgShqtV6j9G7HzatthP-yg9tDV198xILScflYHAgNPWGiJUZcZoar1_FSi9ynxlJSonnkuAw6epwPYk1lvIKZrK5ofTHizmOBUHI_b-xyVXIzoQw",
        "Scope": "openid profile"
      }
trce: IdentityServer4.Endpoints.AuthorizeEndpoint[0]
      End authorize request. result type: IdentityServer4.Endpoints.Results.AuthorizeResult
trce: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking result: IdentityServer4.Endpoints.Results.AuthorizeResult
dbug: IdentityServer4.Hosting.EndpointRouter[0]
      Request path /connect/token matched to endpoint type Token
dbug: IdentityServer4.Hosting.EndpointRouter[0]
      Endpoint enabled: Token, successfully created handler: IdentityServer4.Endpoints.TokenEndpoint
info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking IdentityServer endpoint: IdentityServer4.Endpoints.TokenEndpoint for /connect/token
trce: IdentityServer4.Endpoints.TokenEndpoint[0]
      Processing token request.
dbug: IdentityServer4.Endpoints.TokenEndpoint[0]
      Start token request.
dbug: IdentityServer4.Validation.ClientSecretValidator[0]
      Start client validation
dbug: IdentityServer4.Validation.BasicAuthenticationSecretParser[0]
      Start parsing Basic Authentication secret
dbug: IdentityServer4.Validation.PostBodySecretParser[0]
      Start parsing for secret in post body
dbug: IdentityServer4.Validation.SecretParser[0]
      Parser found secret: PostBodySecretParser
dbug: IdentityServer4.Validation.SecretParser[0]
      Secret id found: xxx-mvc
trce: IdentityServer4.Stores.ValidatingClientStore[0]
      Calling into client configuration validator: IdentityServer4.Validation.DefaultClientConfigurationValidator
dbug: IdentityServer4.Stores.ValidatingClientStore[0]
      client configuration validation for client xxx-mvc succeeded.
dbug: IdentityServer4.Validation.HashedSharedSecretValidator[0]
      No matching hashed secret found.
dbug: IdentityServer4.Validation.SecretValidator[0]
      Secret validators could not validate secret
fail: IdentityServer4.Validation.ClientSecretValidator[0]
      Client secret validation failed for client: xxx-mvc.
trce: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking result: IdentityServer4.Endpoints.Results.TokenErrorResult
Run Code Online (Sandbox Code Playgroud)

小智 6

使用此网站获取您的秘密的 Base64 编码 sha256 https://hash.online-convert.com/sha256-generator

它为“秘密”产生以下结果

hex: 2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b
HEX: 2BB80D537B1DA3E38BD30361AA855686BDE0EACD7162FEF6A25FE97BF527A25B
h:e:x: 2b:b8:0d:53:7b:1d:a3:e3:8b:d3:03:61:aa:85:56:86:bd:e0:ea:cd:71:62:fe:f6:a2:5f:e9:7b:f5:27:a2:5b
base64: K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=
Run Code Online (Sandbox Code Playgroud)

获取base64结果并将其放入appsettings.config

"Clients": [
  {
    ...
    "ClientId": "clientId",
    "ClientSecrets": [ { "Value": "K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=" } ],
    ...
  },
Run Code Online (Sandbox Code Playgroud)

然后在你的 C# 中

{
      ...
      ClientId = "clientId",
      ClientSecret = "secret",
      ...
 }
Run Code Online (Sandbox Code Playgroud)

对我有用


Nan*_* Yu 3

您可以在IdentityServer4.Models.HashExtensions中使用 Identity Server 4 的算法。

在一个应用程序中运行以下方法:

public string Sha256(string input)
{
    using (var sha = SHA256.Create())
    {
        var bytes = Encoding.UTF8.GetBytes(input);
        var hash = sha.ComputeHash(bytes);

        return Convert.ToBase64String(hash);
    }
}
Run Code Online (Sandbox Code Playgroud)

K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=如果密码是 ,结果将是secret。将该值放入 application.json 应该可以:

"ClientSecrets": [ { "Value": "K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=" } ],
Run Code Online (Sandbox Code Playgroud)