简体   繁体   中英

Generate JWT with certificate thumbprint with JSON Web Token Handler for .Net

I'm starting a new task where I have to process thumbprint from JWT. We use JSON Web Token Handler For the Microsoft .Net Framework. There is already an implementation used in tests that generates JWT without x5t filed in header. It looks like this:

var handler = new JwtSecurityTokenHandler();
      var securityKey = new InMemorySymmetricSecurityKey(Any.Array<byte>(1024));
      var desc = new SecurityTokenDescriptor
      {
        TokenIssuerName = "MSI",
        Lifetime = new Lifetime(null, DateTime.UtcNow.AddDays(10)),
        SigningCredentials = new SigningCredentials(securityKey, "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", "http://www.w3.org/2001/04/xmlenc#sha256"),
      };

      var identity = new ClaimsIdentity();
      identity.AddClaim(new Claim("scope", "msi_unsapi_presence.watch"));
      identity.AddClaim(new Claim("scope", "msi_unsapi_location.watch"));
      identity.AddClaim(new Claim("scope", "msi_unsapi_groupmgt.read"));
      identity.AddClaim(new Claim("scope", "msi_unsapi_groupmgt.write"));
      var jwtToken = handler.CreateToken(desc);
      return jwtToken;

And the token it produces: {"typ":"JWT","alg":"HS256"}.{"scope":["msi_unsapi_presence.watch","msi_unsapi_location.watch","msi_unsapi_groupmgt.read","msi_unsapi_groupmgt.write"]} I try to set AttachedReference property of SecurityTokenDescriptor as the following AttachedReference = new X509ThumbprintKeyIdentifierClause(Any.Array<byte>(1024)) to have x5t field filled in the token (I don't care about the exact value, I just need it to exist in token for test purpose) but the token produced still doesn't have this field set. How can I generate the token with not empty x5t filed in header, preferably modifying the existing code?

here's the implementation for your customJsonWebTokenFormat :

you can really add anything to it with the payload.add().

          public class yourJsonWebTokenFormat: ISecureDataFormat<AuthenticationTicket>
            {
                public string Protect(AuthenticationTicket data)
                {
                DateTime notBefore = DateTime.UtcNow;
                DateTime expires = notBefore + TimeSpan.FromHours(1); //validity timer.

         SigningCredentials cred= new SigningCredentials(); // your signing credentials.
                    JwtHeader header = new JwtHeader(cred);
header.add("x5t","your value");
                    JwtPayload payload = newJwtPayload(ConfigurationManager.AppSettings["Issuer"],data.Properties.Dictionary["audience"], data.Identity.Claims, notBefore, expires);
        payload.add("x5t","your x5t to json property");

                    var jwtToken = new JwtSecurityToken(header, payload);
                    var handler = new JwtSecurityTokenHandler();
                    var jwt = handler.WriteToken(jwtToken);
                    return jwt;
                }
    }

then in your OAuth Config :

     OAuthAuthorizationServerOptions OAuthServerOptions = new 

    OAuthAuthorizationServerOptions()
                {
    // provider configuration, token authentication expiracy, etc...
Provider = new SampleAuthorizationServerProvider()
                    AccessTokenFormat = new JsonWebTokenFormat()
                };

requesting a token will now call your yourJsonWebTokenFormat.protect() method.

you should set the identity you built in your sample in a AuthenticationTicket in your own OAuthAuthorizationServerProvider.

something like that :

        public class SampleAuthorizationServerProvider : OAuthAuthorizationServerProvider, IOAuthAuthorizationServerProvider
        {
           public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
                {
        // do AD check or other stuff needed to validate the user here
            var ticket = new AuthenticationTicket(identity, props); // props here is a AuthenticationProperties Dictionnary with other stuff that you want in your JwtToken
    context.Validated(ticket);
        }

        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
//do some check...
context.Validated();
}
    }

so you endup with 2 class you need to implement : ISecureDataFormat<AuthenticationTicket> and

OAuthAuthorizationServerProvider, IOAuthAuthorizationServerProvider

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM