How to get publickey to validate Azure token - spring-boot

I am trying to validate Azure token in spring boot which is coming from angular app in header.
I found below steps to validate Token:
get Public key
verify signature by passing public key
verify claims
but I am not sure how to get public key in Java.
Any suggestions please?
Thanks

Related

Invalid signature Azure access token jwt.io

I generated access tokens using Azure AD+ Spring Boot using Outh2 Authorization code grant flow.
But when I try to validate the token generated (using Spring Boot resource server apis) I get an "Invalid Signature" Error.
Question is I get "Invalid Signature" error when I copy/paste the token in jwt.io as well.
Jwt.io image
Does that mean that my access token does not actually have a valid signature ??
When I switched the Algorithm from RS256 to HS256 in jwt.io it says that the signature was verified. Which I found strange.
Is there any way I can know what algorithm is used by Azure AD to generate Access tokens after successful user login??
I tried to reproduce the same in my environment and got the below results:
I generated Authorization code by using the below endpoint:
https://login.microsoftonline.com/TenantID/oauth2/v2.0/authorize?
client_id=ClientID
&response_type=code
&redirect_uri=RedirectURI
&response_mode=query
&scope=openid profile
&state=12345
I generated the access token using Authorization code grant flow using Postman by using below parameters:
https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
client_id:ClientID
client_secret:ClientSecret
scope:openid profile
grant_type:authorization_code
redirect_uri:RedirectURI
code:code
When I decoded the above access token, I got the same error like below:
Note that: Graph API token doesn't require validation (aud is Graph). Graph access token will not pass Signature verification in the code because access token is not for the application.
To resolve the issue, you can try replacing the scope as api://ClientIDofApp/.default while generating the token like below:
The access token decoded successfully without any error like below:
Reference:
openid - Signed JWT rejected: Invalid signature azure-spring-boot (github.com)

Spring boot verify google oauth token

I have used spring-security-oauth2-client for social login with google and facebook. Now while making mobile application I have to use in-app login where I am getting id-token, access-token, providerID etc from Google.
How I can connect my api server with this token? Token from google gives me following error while validating
Java.lang.IllegalArgumentException: Key bytes can only be specified for HMAC signatures. Please specify a PublicKey or PrivateKey instance.
My Goal is simple.
verify user login
If user exists then give JWT token otherwise create user and give token to access api's
How can I do this?

jwt validation in backend springboot

Im looking to create an angular application which login against a new authentication server created in springboot and return a jwt.
The idea is to create the application to be able to generate and sign the jwt token with a private key based on the user/password provided in the screen, the authentication server will validate the login information in database and generate the jwt token.
After that, a request will be sent to another microservice and in here I need to be able to validate the token, but this microservice wont be connected to the authentication service or database in any way, it will just validate the integrity of the token using a public key.
Im looking everywhere and I dont find the clue to be able to validate the token, I found this piece of code but for some reason when I execute the rest API exposed this code is not executed:
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
Resource resource = new ClassPathResource("public.txt");
String publicKey = null;
try {
publicKey = IOUtils.toString(resource.getInputStream(), Charset.defaultCharset());
} catch (final IOException e) {
throw new RuntimeException(e);
}
converter.setVerifierKey(publicKey);
return converter;
}
Does what im trying to do makes any sense?
Thanks
Regards
Your auth server will will need to be the single issuer of JWTs to your microservices. So, when a user logs in and successfully authenticates, your auth server will issue a JWT signed with a private key (signing MUST be asymmetric - RS256 is one example) you keep on the auth server only; do not give this private key to other microservices that you wish to validate JWTs inside of. What you can do is derive a public key based on the private key you sign your tokens with and publish that to an endpoint on your auth server that requires no authentication - the public key will be represented in the form of a JWK (see link to spec). Google does something similar here. Then, in each of your microservices, you will need to devise a way to make a GET request to the public key endpoint on your auth server every X minutes and cache the public key in each microservice.
Then whenever a request comes into one of your microservices, you grab the JWT, check its validity, and grant access/authorization if the token is valid. The beauty of using a private/public key pair and asymmetric key signing is that you can validate a token based on the public key alone, but not sign it. So as long as each service has the public key from your /cert endpoint, they can validate a token without ever needing to talk to the auth server or knowing the private key.
This will require a little more work up front, but will yield you massive amount of ease, flexibility, and peace of mind in the future knowing only one source knows your private key.
I suggest using this library to do JWT validation.
The overall architecture will end up looking something like this:

Azure B2C Access Token NULL Spring OAuth 2.0

I am trying to get a custom web application to work with Azure B2C OAuth and the Spring OAuth2.0 framework.
The authentication leg comes back fine and I receive a JWT token. When the request for a token occurs afterwards I get the following error:
java.lang.IllegalStateException: Access token provider returned a null access token, which is illegal according to the contract.
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:223) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173) ~[spring-security-oauth2-2.0.8.RELEASE.jar:na]
...
From some debugging of the spring code I can see the token is expected to be called access_token as seen in the OAuth2AccessToken class. From looking at the B2C tutorials their token is called token_id. Furthermore the applications.yml config I have for my spring application has a field called tokenName. Surely this should be used to pick up the token name field instead of the hardcoded static variable as above.
Am I missing something and is there a solution to my problem. Can I override the token name field used by the spring OAuth framework?
I'm going to go ahead and post this as the answer.
I started with the Spring tutorial, and made some modifications to it. For a working example, see the public github repo: https://github.com/Pytry/azure-b2c-oauth2.git
To properly parse the token received you will need:
A custom implementation of an AccessToken that will parse the JWT, pulling and setting variables as required by spring security. I extended DefaultOAuth2AccessToken and added this parsing to a private method called by the constructor.
If you are going to verify the RSA signature using the public keys, you will need a custom JWT object so you can access the header information. I chose to extend springs JWT, and add some parsing on creation to access the header. It may also be useful to have some custom Pojos for parsing the returned meta data and rsakey information into.
An extension of the JwtAccessTokenConverter, with an overridden "decode" method. Azure does not give a "user_name" nor a "client_id" in the returned id_token, so you need to add those. I also included some logic in the super class that I found suefull (such as converting strings to int/long when appropriate).
A custom UserDetailsManger to override the default in memory one. This can either retrioeve user information from the GraphAPI, or it can load it from your user repository. I actually did not create either of these, and instead used the default in memory service, but injected it into the token converter; then whenever a user was properly authenticated, I would add them to the managers store, or update them if they already existed.
There are a few things I have not done yet.
RSA verification is not being done. Any help on this is appreciated.

How to sign data(string) in wp8

App will receive a token (string) from server. I want to sign this token with private key. I will pass on corresponding public key and signed token back to server in next request. Now server will validate that token using public key to check whether request is coming from authenticated user.
How to achieve this?

Resources