IdentityServer client authentication with public/private keys instead of shared secrets

前端 未结 2 746
予麋鹿
予麋鹿 2021-02-02 01:30

I\'m trying to use public/private keys instead of a shared secret for client secrets with IdentityServer4. This approach is documented here.

If it was a shared secret,

2条回答
  •  孤街浪徒
    2021-02-02 02:14

    Figured this out thanks to the unit tests in IdentityServer4!

    When using public/private authentication, client_secret is not used. Rather, a client_assertion is used, which is a JWT token.

    Here is sample code for the token request. client.pfx is the certificate bundle generated from the steps above in the question.

    var now = DateTime.UtcNow;
    var clientId = "abc";
    var tokenEndpoint = "http://localhost:5000/connect/token";
    
    var cert = new X509Certificate2("client.pfx", "1234");
    
    // create client_assertion JWT token
    var token = new JwtSecurityToken(
        clientId,
        tokenEndpoint,
        new List
        {
            new Claim("jti", Guid.NewGuid().ToString()),
            new Claim(JwtClaimTypes.Subject, clientId),
            new Claim(JwtClaimTypes.IssuedAt, now.ToEpochTime().ToString(), ClaimValueTypes.Integer64)
        },
        now,
        now.AddMinutes(1),
        new SigningCredentials(
            new X509SecurityKey(cert),
            SecurityAlgorithms.RsaSha256
        )
    );
    
    var tokenHandler = new JwtSecurityTokenHandler();
    var tokenString = tokenHandler.WriteToken(token);
    
    
    // token request - note there's no client_secret but a client_assertion which contains the token above
    var requestBody = new FormUrlEncodedContent(new Dictionary
    {
        {"client_id", clientId},
        {"client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"},
        {"client_assertion", tokenString},
        {"grant_type", "client_credentials"},
        {"scope", "api1 api2"}
    });
    
    
    var client = new HttpClient();
    var response = await client.PostAsync(tokenEndpoint, requestBody);
    var tokenRespone = new TokenResponse(await response.Content.ReadAsStringAsync());
    

提交回复
热议问题