Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate a JWT from WSO2 API Manager

What is the recommended way for validating that a JWT was issued by a specific API Manager instance in a case where the backend web service lives on a separate server and needs to be certain that a given request passed through the APIM Gateway authentication and authorization mechanisms?

I know that the header fields in the JWT include an 'x5t' field which is an encoded reference to a certificate in the tenant key store, as detailed here:

https://asankastechtalks.wordpress.com/2013/12/05/obtaining-certificate-used-to-sign-a-jwt/

Since the backend web service is on a separate server, do we need to distribute the public key to it somehow? Also, how can we update the certificate that is used to sign the JWT since right now it is using the default?

like image 739
user2789361 Avatar asked Mar 14 '14 15:03

user2789361


2 Answers

The data in the x5t is not the entire certificate, it is only a hash to help you identify if a certificate you have is the same one. This means that you do need to upload the public certificate to the receiving service.

With https the public certificate can be retrieved in the handshake, the client can then check that this certificate is signed by a trusted CA. With this validation however there is no such mechanism, as a result you can't just trust the CA you have to trust each public certificate.

There is another optional header 'x5u' which includes a url link to the public certificate but APIM does not set that value.

like image 120
Louis Zelus Avatar answered Nov 09 '22 10:11

Louis Zelus


This is how you can get the certificate from the local store using the x5t hash in the WSO2 token as a lookup:

// Use JwtSecurityTokenHandler to validate the JWT token
var tokenHandler = new JwtSecurityTokenHandler();

// Read the JWT
var parsedJwt = tokenHandler.ReadToken(token);

// Get X509 public certificate
var signerAlgorithm = ((JwtSecurityToken)parsedJwt).SignatureAlgorithm;
var signerHash = ((JwtSecurityToken)parsedJwt).Header["x5t"];
var thumbprint = Encoding.UTF8.GetString(Convert.FromBase64String(signerHash.ToString()));

X509Store store = new X509Store(StoreName.TrustedPublisher);
store.Open(OpenFlags.ReadOnly);
var cert = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false)[0];
like image 43
tgitchel Avatar answered Nov 09 '22 09:11

tgitchel