AzureAD / microsoft-authentication-library-for-js

Microsoft Authentication Library (MSAL) for JS
http://aka.ms/aadv2
MIT License
3.66k stars 2.65k forks source link

Roles undefined in idTokenClaims but exist in token #4802

Closed NidalGhonaim closed 2 years ago

NidalGhonaim commented 2 years ago

Core Library

MSAL.js v2 (@azure/msal-browser)

Core Library Version

2.22.1

Wrapper Library

MSAL React (@azure/msal-react)

Wrapper Library Version

1.3.1

Description

idTokenClaims.roles returns undefined. The claims I get are: aud, exp, iat, iss, name, nbf, nonce, oid, preferred_username, rh, sub, tid, uti, ver ... but no roles. When I print the token from msalInstance.acquireTokenSilent and decode it on https://jwt.ms/ I can see the roles I assigned to the account.

MSAL Configuration

export const msalConfig: Configuration = {
  auth: {
    clientId: process.env.REACT_APP_MSAL_CLIENT_ID || "",
    authority: process.env.REACT_APP_MSAL_AUTHORITY,
    redirectUri: process.env.REACT_APP_MSAL_REDIRECT_URL,
  },
  cache: {
    cacheLocation: "sessionStorage",
    storeAuthStateInCookie: false,
  },
};

Relevant Code Snippets

const { accounts, inProgress } = useMsal();
let roles = accounts[0].idTokenClaims.roles; // <-- returns undefined


### Identity Provider

Azure AD / MSA

### Source

External (Customer)
jasonnutter commented 2 years ago

When I print the token from msalInstance.acquireTokenSilent and decode it on https://jwt.ms/ I can see the roles I assigned to the account.

When you call msalInstance.acquireTokenSilent, are you looking in the accessToken?

NidalGhonaim commented 2 years ago

When you call msalInstance.acquireTokenSilent, are you looking in the accessToken?

@jasonnutter yes.

svrooij commented 2 years ago

@NidalGhonaim can you confirm you are using the same client ID for both the API and the client? If this is not the case, the ID token is to tell your client Hey this is user x accessing your client application and the access token is to tell the API User x has this permissions for your API application

In the identity token you will get the roles that the user has assigned in you Client application. If you check the access token, it will contain the roles the user has assigned for the API. And if you use the same Client ID in both the client and the api, both token will have the roles claim

NidalGhonaim commented 2 years ago

@svrooij Ah! ... now I understand. Thank you for your response.

I'm using different app registrations for the client (SPA) and the API, and I am trying to check if the user has the permission to access certain API endpoints. Is my approach of decoding the the token correct? Or should I duplicate the roles (from the API app registration) to the client app registration?

derisen commented 2 years ago

@NidalGhonaim the resource server (API) should decode and validate the access token, so that's fine. If you need to adjust the UI based on user's role then duplicating roles on the client app registration also makes sense (here's an example doing that).

NidalGhonaim commented 2 years ago

@derisen It all makes sense now. Thank you very much.

svrooij commented 2 years ago

@NidalGhonaim and if you don’t want to replicate the roles in the client app. You can use the client id of the api in the client app, but I’m not sure what the official policy on that is.

ehsan-shv commented 11 months ago

There's still something wrong with accounts but instance.getActiveAccount() works for me:

  const { instance } = useMsal()
  useEffect(() => {
    console.log('getActiveAccount', instance.getActiveAccount())
  }, [ instance, instance.getActiveAccount]);