I need to read the raw ID token from a login using msal.js (#azure/msal-react). Authentication works fine and I'm able to read the account using getAllAccounts(). But I cannot seem to find any way to extract the raw ID token.
I need to pass the token to a REST API in order to verify the user. I don't want to use access tokens at this point. Is there some way to get the raw ID token? I can see it in localStorage, but I'd rather not grab it directly from there as I suspect that is not supported behavior.
This guy figured it out: https://github.com/shawntabrizi/Microsoft-Authentication-with-MSAL.js
The idToken property of the object returned by the MSAL authentication calls (such as loginPopup) is the raw JWT.
Example:
PublicClientApplicationInstance.loginPopup(loginRequestConfig).
then(response => console.log(response.idToken))
Related
What I ideally want to achieve is to be able to Login with Google SignIn, and put authentication on my Nodejs server's endpoints.
What I have done till now is log in the user in the browser, and send the IdToken to the server, validate this TokenId using verifyIdToken() using this link.
https://www.google.com/search?q=verify+idToke&rlz=1C5CHFA_enIN936IN936&oq=verify+idToke&aqs=chrome..69i57j0i13l2j0i13i30l3j69i60l2.12008j0j7&sourceid=chrome&ie=UTF-8
Question:
Once verified, should I generate an access_token using some package, and use that to secure my server's API? Or Use Google SignIn's IdToken as an access token for it?
Or Is there some other flow I'm not getting?
The id_token contains information about the user i.e. email, name, and profile picture.
If that's all that your application needs then the access_token won't be of use to you.
If you're trying to access/modify data belonging to the user, (i.e. trying to add an event to their calendar using the calendar api) then you need the access_token. The access_token is what will give you access to the user's account. If your application requests offline access to the user data then you will also receive something called a refresh_token that will let you regenerate your access token once it expires. If you add the refresh token to your oAuthClient it should automatically renew the access token for you when you make an api call.
Based on what you described I don't think you need the access_token and the id_token might be all you need.
More information is available on this page: https://developers.google.com/identity/protocols/oauth2
I am using the Microsoft Graph API along with Microsoft Authentication Library (MSAL) to acquire access tokens and I can successfully retrieve the access token, id token and refresh token. I can also successfully validate the id token. However, I cannot do the same for the access token as I'm getting this error:
raise InvalidSignatureError('Signature verification failed')
jwt.exceptions.InvalidSignatureError: Signature verification failed
I've reviewed as best as I can the microsoft documentation regarding validation here:
Microsoft identity platform access tokens
For validation, I can successfully decode using the jwt.ms site for jwt validation. So I know the tokens are good. I can see from the decode the claims and extract the aud(audience) and iss(issuer). These values are not the same for the id token (which I can successfully validate).
I am using the public keys from the following url as documented:
https://login.microsoftonline.com/<TENANT ID>/discovery/keys
So, what I missing in regards to validating the access token? (if I can validate the id token with no issues). How else can i troubleshoot this?
Jim's answer is correct and there are 2 use cases really - so it depends what you are trying to do:
Getting an access token for Microsoft resources - such as Graph - in which case you don't validate them
Getting a token for your own API resources, in which case you need to validate them. For this to work you need to 'expose an API scope' to get a different type of access token
Behaviour is not intuitive in my opinion, since I like to build standards based solutions. If it helps, here is a visual blog post of mine on getting the second scenario above working.
As far as I knew, we do not need to validate Microsoft graph signature. Because MsGraph recognized an opportunity to improve security for users. They achieved this by putting a ‘nonce’ into the jwt header. The JWS is signed with a SHA2 of the nonce, the nonce is replaced before the JWS is serialized. To Validate this token, the nonce will need to be replaced with the SHA2 of the nonce in the header. Now this can change since there is no public contract. So When calling Microsoft Graph, you should treat access tokens as opaque. For more details, please refer here and here
The version of the AcquireTokenAsync constructor I use returns a Security Token
I noticed some other versions of this constructor return an Access Token
After reading around, I still haven't found the difference. What is the difference?
The version of AcquireTokenAsync method that you have mentioned in your question returns Access Token. So there is no difference.
Notice the Returns section in the same documentation that you have linked in question.
After your call to AcquireToken is done, you should be able to get the access token from result using the direct property named AccessToken like result.AccessToken
You can also verify this by trying to decode the token that you get back using https://jwt.ms
Access tokens enable clients to securely call APIs protected by Azure. Generally the client that acquires the token should treat it as an opaque string, because it's contents are meant for the actual resource API that the client is trying to access.
You can read more about Access Tokens and the claims inside here on Microsoft Docs
Given an auth token, originally received from Spotify Android/iOS SDK, I want to check with Spotify that the token I am holding is valid. Is there a minimal endpoint for doing this?
Ideally something not data-intensive, as I just want to know if the token is valid. This must be done with Web API and not SDK.
There is no API endpoint for checking whether the access token is still valid. Usually you would store it along with the expires_in value that tells you until when it is valid.
An alternative is making a request to any endpoint from the Web API passing the access token. You will get a 401 Unauthorized status code back if the token has expired.
I need to get the nameidentifier from the token that Azure AD sends. I am assuming this is unique for each user of the AD and have some custom authorization logic based on it.
For example,
AuthenticationResult result = authenticationContext.AcquireToken(webApiResourceId, certificateCredential);
string accessToken = result.AccessToken;
This accessToken is sent to the WebAPI as AuthenticationHeader, that decrypts it and fetches the nameidentifier as
Claim tenantClaim = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier);
But this process on the WebAPI is transparent and is performed by ADAL.However, i need to get the NameIdentifier at client side itself.
Is there any way I can fetch the NameIdentifier at client side itself, by decrypting the AccessToken? I do not seem to find the correct answer upon searching.
Can you expand on why you need the NameIdentifier on the client? Note that the client side does not do perform any validation on the token, hence you should not take any access control decisions on the client based on the token content. The server side can take decisions based on the token content given that the token itself is validated before making its content available to the application.
Another important consideration: the access token is meant for the web API and the client should not try to read it. Even if you manage to read it, you'd be generating extremely brittle logic as the format can change at any time, it might be encrypted with a key that your client should not have, and so on.
If you need access to the NameIdentifier on the client for different reasons, you can inspect the id_token. The id token is another token that is sent alongside the access token. The id token is meant for the client, hence it is safe for you to look at. You can find it as a property in AuthenticationResult.
HTH
V.