How to get public certificate for id_token in openam? - jwt

I’m using openam OAuth 2.0/OpenID access_token end-point to get an id_token. The id_token contains a RS256 signature.
I need to verify this token. So from where can I get the “public certificate” that used to sign this token?
I found a public key certificate in here,
%BASE_DIR%/%SERVER_URI%/keystore.jks. But it says invalid after validating with this certificate.

You can use the well-known configuration endpoint to find out the jwks_uri for the OIDC provider. Then it will be just a matter of selecting the right key from the jwks_uri response based on the "kid" value in the JWT.
Of course looking at jwks_uri endpoint will only make sense if the signing algorithm for the JWT is based on asymmetric keys (RS*, ES*).

Related

Jwt.io self populating the signature

I am very new to jwt and signature validation. I had a very basic query.
I am generating a token from MSAL(AAD).
When I use the token in jwt.io, I can see that it automatically populates the secret key and marks the signature as verified. How does jwt.io know about this?
From generating token point of view, I didn't mention anywhere explicitly to generate the token with any secret.
You don't show the details of your token here (which is ok), but I assume the token has a kid and maybe also a jku in the header.
The kidis the Key Id, and the jku the JSON Web Key Set URL.
Under that URL (you can paste it to your browser to see) you can find a set of JWKs (JSON Web Keys), basically a collection of public keys in a special format. In case of tokens issued by AAD you the JWKS_URI can be found on https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration.
JWT.io can read this information and find the key with the given kid and verify the token based on that.
This Q/A explains the verification of JWTs issued by AAD in more detail.

How to obtain public certificate from Azure Active Directory

Our .net core based web api needs to validate the the JWT access tokens received from third party but trusted AAD. In order to do that token signature validation our web api needs to have public certificate of trusted AAD. This functionality is in POC phase. So how to get/download public certificate (.cer file) of AAD?
I would recommend that you use the standard JWT Bearer authentication scheme which handles this aspect for you.
You specify the Authority and ClientId to it and it'll handle the rest.
But if you are curious about the details,
I can explain a bit.
First you take your authority, e.g. https://login.microsoftonline.com/company.com/v2.0 (or https://login.microsoftonline.com/company.com if you are using v1 tokens).
We add /.well-known/openid-configuration to the authority to get the metadata URL: https://login.microsoftonline.com/company.com/v2.0/.well-known/openid-configuration.
That metadata URL gives us JSON which includes the jwks_uri property.
E.g.:
"jwks_uri":"https://login.microsoftonline.com/tenant-id-here/discovery/v2.0/keys"
When we navigate to this URL, we get the public signing keys for Azure AD.
This is all handled under the covers by the JWT Bearer authentication handler though, so you should not implement it yourself.

PayPal id_token verification

I'm implementing "Log In with PayPal" functionality. Should be fairly simple, but unfortunately PayPal lacks documentation (only some basic things are described).
I get authorization_code using "Log In with PayPal" widget. Than I make a request to https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice and get JSON with access_token, refresh_token and id_token. I want to get unique user identifier, so I decode id_token, but I'm not able to verify signature of my id_token. Id_token header contains {"alg": "HS256", "typ": "JWT"}.
What secret should I use? Tried my app's secret (same that I use to access tokenservice), but it didn't work (using https://jwt.io/ debugger).
PayPal is not OpenID connect compliant. This answer explains the reasons.
PayPal expose a configuration endpoint - https://www.paypalobjects.com/.well-known/openid-configuration.It only support HS256 and does not support or mention about RS256. This could be due to a proprietary validation for ID token. For example a id token used as a bearer token.
Alternative solution would be to invoke userinfo endpoint as described by document. This endpoint can be invoked using access token and document says it would return the user_id
user_id - identifier for the end-user at the issuer.
Although it seems that user_id found in the userinfo is different from sub that could be extracted from id_token.
How to find public keys if signing algorithm is RS256
ID token is a JWT. As you have found out, it contains a JWS signature which acts as a MAC.
This signature is a signed using a private key. The receiver of the id token can validate the token using the public key. To find the public key, openid conenct specify a discovery document. You can read more about this from the specification
In the discovery document, you get a special endpoint to infer the configuration .well-known/openid-configuration. And one of the must have metadata of the configuration response is jwk_url
jwks_uri
REQUIRED. URL of the OP's JSON Web Key Set [JWK] document. This
contains the signing key(s) the RP uses to validate signatures from
the OP. The JWK Set MAY also contain the Server's encryption key(s),
which are used by RPs to encrypt requests to the Server. When both
signing and encryption keys are made available, a use (Key Use)
parameter value is REQUIRED for all keys in the referenced JWK Set to
indicate each key's intended usage. Although some algorithms allow the
same key to be used for both signatures and encryption, doing so is
NOT RECOMMENDED, as it is less secure. The JWK x5c parameter MAY be
used to provide X.509 representations of keys provided. When used, the
bare key values MUST still be present and MUST match those in the
certificate.

jwt - Django-rest-framework-jwt authentication in microsevices

I am newbie in JSON web token and micro services. I read in an articles that if i share the private, all services can verify user on their own. Then i tried to implement an application to practice.
Basically, I have two services A and B. A is used for authentication. Then, I tried implement a API that required authentication in service B. But when I used a token generated by authentication A in API, 401 status code and "Invalid signature." were returned.
So anyone can explain to me what I did wrong?
"Invalid signature" implies that the secret key that you used to encode the token doesn't match with the secret key you used for decoding it.
Make sure that the secret you are using for encoding and decoding are same.
For more info visit the JWT's site.
First of all the service to service communication only need public key to be shared in case of an asymmetric key pair such as RSA or ECDSA. The public key shared can be used to verify the signature and each service needs to sign JWT using their private key. You have to take care of securing the private key and make public key accessible to other services.
Verifying the user is a completely different use case. The user existence should be checked in database and a password check can be made which is authentication is all about. The JWT can be used to pass the user information along with access right with a signature done by the application using private key so that no one able to generate the same token. NOTICE : Signature is done using private key. In this way you have both authentication and authorisation using JWT.

Why does my JWT Token' from Amazon Cognito have an invalid signature?

I am working on Amazon cognito. I am trying to decode from https://jwt.io
eyJraWQiOiJRaGF4STZGbXB5Y3Z3dUV5TUZJUk9FTm5MTDJKTiswMzVVak5MNTEycjZvPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJhYjI0YzExYS1mNjZhLTRjMjktOWVhNy0yMWQwMTc2NmZlN2IiLCJhdWQiOiIxY2ZxNjJubjNlZmNpdWFpYnFldmlxbHU4OSIsInRva2VuX3VzZSI6ImlkIiwiYXV0aF90aW1lIjoxNDk0Njg1MjQwLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtZWFzdC0xLmFtYXpvbmF3cy5jb21cL3VzLWVhc3QtMV9oM3F4WGVPQzQiLCJjb2duaXRvOnVzZXJuYW1lIjoidGVzdHNhbmRlZXAxIiwiZXhwIjoxNDk0Njg4ODQwLCJpYXQiOjE0OTQ2ODUyNDAsImVtYWlsIjoic2FuZGVlcC5qYWtrYXJhanVAZm9jYWxjeG0uY29tIn0.ZRsYZZwxUnqL4FfuWhD-w8xQWoQQkuj4rYCYPqQehcq1SMe0Vww2GIY4-sr9RgwjVxhOo4WqIQT8LzSn_tFBF504h5xGpp5fD37rIJZ49rC3naH7tC0nHwKSswi6C6x8BlIPi4QAnlP49SZMoIEPEnQig9F6wzlDfb-cjw0R2q61Em-e0cpBM8lbjxCrgBF2-PbXFqwEfncEUkwb93qZHo4Wk3pYH3d-9aXzZg6Xc4CNZfehAUZ7qknq2qtaSI3tH-EXGYmytjoVwcF5jIvej2OATrQf_JbfBNSxC96oA_CglWVKvp2rPrqlZzDCd0Se68TjZvKSbW7XtKX_DzI5ww
It says the signature invalid. I have tried many tokens I am always getting this.
Why does it report that the signature is invalid?
#jps is correct. You need to download the JWKs for your Cognito User Pool before you can verify the signature of the JWT.
Download your Cognito User Pools JWK file: https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json. This for your User Pool is: https://cognito-idp.us-east-1.amazonaws.com/us-east-1_h3qxXeOC4/.well-known/jwks.json
Find your Identities kid value. The value from the token you provided is: "QhaxI6FmpycvwuEyMFIROENnLL2JN+035UjNL512r6o=".
You then need to generate the Public Key that matches the data provided from the JWKs file, that matches your kid key. This is blogged about here: https://aws.amazon.com/blogs/mobile/integrating-amazon-cognito-user-pools-with-api-gateway/ (look further down the blog post for how to generate the Public Key).