简体   繁体   中英

How do you read Roles/Permissions using MSAL-ANGULAR

So I've successfully integrated Azure AD authentication in my angular site as per the instructions in msal-angular and now I'm at the point where I'm looking to define and leverage roles and permissions to provide more granular control of what a user can and can't do.

From what I've been able to determine I can define roles by following this set of instructions ( https://docs.microsoft.com/en-us/azure/architecture/multitenant-identity/app-roles ) but msal-angular doesn't seem to expose this upon logging in - or at least I haven't found instructions on how to do this just yet.

Perhaps I'm missing something. Any suggestions would be appreciated

To get the groups a user belongs to, you will need to add directory.read.all to your scope in your Angular app and also in the API permissions in the Azure app settings.

let graphUser = await graphClient.api('/me').get();
let graphUserGroups = await graphClient.api(`/users/${graphUser.id}/memberOf`).get();

let user = new User();
user.id = graphUser.id;
user.displayName = graphUser.displayName;
// Prefer the mail property, but fall back to userPrincipalName
user.email = graphUser.mail || graphUser.userPrincipalName;

graphUserGroups.value.forEach(group => {
    user.groups.push({
        group_id: group.id,
        group_name: group.displayName
    });
});

(Thanks goes to stillatmylinux)

FYI: Here's my working angular 7 solution (simplified for the sake of readability):

import { MsalService, BroadcastService } from '@azure/msal-angular';
import { Client } from '@microsoft/microsoft-graph-client';

private subscription: Subscription;
private graphClient: Client;
private memberRoles: any[];

constructor(
  readonly auth: MsalService,
  readonly broadcast: BroadcastService
) {
  // Initialize Microsoft Graph client
  this.graphClient = Client.init({
    authProvider: async (done) => {
      let token = await this.auth.acquireTokenSilent(["User.Read", "Directory.Read.All"])
        .catch((reason) => {
          done(reason, null);
        });

      if (token) {
        done(null, token);
      } else {
        done("Could not get an access token", null);
      }
    }
  });

  this.subscription = broadcast.subscribe("msal:loginSuccess",
    () => {
      //Get associated member roles
      this.graphClient.api('/me/memberOf').get()
        .then((response) => {
          this.memberRoles = response.value;
        }, (error) => {
          console.log('getMemberRoles() - error');
      });
  });
}

You can change the manifest to get these delivered in the token itself.

The sample (its for .NET though), explains this in detail

You only needs User.Read permission and to use memberof v1. Use import * as MicrosoftGraph from '@microsoft/microsoft-graph-client'; to fix microsoft-graph-client header export bug. uniqueId is your AzureAD user id.

private loginSuccess(uniqueId: string) {
     console.log('LOGIN SUCCESS ', uniqueId);
     (this.graphClient = MicrosoftGraph.Client.init({
      authProvider: async (done) => {
        let param: AuthenticationParameters = { authority:"https://login.microsoftonline.com/{TenantId}",
                                              scopes:["User.Read"]
                      };
        let response = await this.authService.acquireTokenSilent(param)
        .catch((reason) => {
          done(reason, null);
          });

        if (response) {
          done(null, response.accessToken);
        } else {
          done("Could not get an access token", null);
        }
      }
    })).api(`/users/${uniqueId}/memberOf`).get()
    .then((response)=>{
        this.groups = response.value;
        console.log("members ok", this.groups);
    },
    (error)=>{
      console.error('memberOf error');
    });

}

With MSAL-ANGULAR (the current stable version "@azure/msal-angular": "^1.1.2 ) You can access the roles from the authentication response(key msal.idtoken ).

With the modern browsers this can be found in Local storage and for the IE this will stored in cookies. Since the msal.idtoken is Jwt, decoding this should provide the user's role.

const token = localStorage.getItem('msal.idtoken');
const payload = jwt_decode(token); // jwt_decode npm package will help you to decode the payload.
console.log(payload);

Alternatively you can even use https://jwt.io/ to manually decode the data.

You can read user roles defined in Azure App Registrations and assigned in Enterprise Application using MsalService:

let allAccounts = this.msalService.instance.getAllAccounts();
if (allAccounts.length > 0) {
  let account = allAccounts[0];
  let roles = account.idTokenClaims.roles;
}

MSAL Angular version:

"@azure/msal-angular": "^2.0.5",
"@azure/msal-browser": "^2.19.0",

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM