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?
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.
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];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With