使用 microsoft-adal-angular 6 和 microsoft-graph-client,我如何验证从 AAD 收到的令牌的权限?

Using microsoft-ada-angular6 and microsoft-graph-client, how do I verify the permissions of the token I receive back from AAD?

我在 Angular 中使用隐式授权工作流和 microsoft-adal-angular6 库对我的应用程序中的用户进行身份验证,然后获取用于访问 Microsoft Graph 的令牌。

身份验证部分正在运行。

并且我可以通过库从 AAD 获取令牌。但是,当我尝试通过客户端(和通过 http)查询图形时,我收到一条无效的受众错误消息(http 查询对 401 的帮助略小)。

statusCode: 401 
   code: "InvalidAuthenticationToken" 
   message: "Access token validation failure. Invalid audience." 
   requestId: "157c3867-3ac6-41e7-aa79-fbd6cc466c4f" 
   date: Tue Mar 03 2020 23:18:44 GMT-0700 (Mountain Standard Time) {} 
   body: "{"code":"InvalidAuthenticationToken","message":"Access token validation failure. Invalid audience.","innerError":{"request-id":"157c3867-3ac6-41e7-aa79-fbd6cc466c4f","date":"2020-03-03T23:18:44"}}"
    __proto__: Object`

这里我设置了我的 ADAL 服务:

`adalConfig = {
  tenant: AppConfig.settings.aad.tenant,
  clientId: AppConfig.settings.aad.clientId,
  redirectUri: AppConfig.settings.aad.redirectUri,
  endpoints: AppConfig.settings.aad.apiEndpoint,
  navigateToLoginRequestUrl: false,
  cacheLocation: AppConfig.settings.aad.cacheLocation
};`

json:

"aad": {
    "requireAuth": true,
    "apiEndpoint": {
        "https://localhost:44371": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "https://graph.microsoft.com/v1.0/": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"  
    },
    "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "resource": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "redirectUri": "http://localhost:4200/frameredirect/",
    "cacheLocation": "sessionStorage",
    "vospEndpoint": "https://localhost:44371",
    "graphEndpoint": "https://graph.microsoft.com/v1.0/",
    "vospAADGroup": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "clientSecret": "",
    "scopes": [
        "GroupMember.Read.All"
    ]
}}`

我为图形端点获取令牌的调用:

private async getAccessToken(): Promise<string> {
const resource =  this.adalService.GetResourceForEndpoint(AppConfig.settings.aad.graphEndpoint);
let result = await this.adalService.acquireToken(resource).toPromise().then((token:string) => {return token;}).catch(error => {return error;});

if(result) console.log(result);
return result;

这是我的代码,用于调用 init 图形客户端并调用 api:

let graphClient = await Client.init({
  authProvider: async(done) => {
    let token = await this.getAccessToken()
    .catch((reason) => {
      done(reason,null);
    });

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

let aadGroupId = AppConfig.settings.aad.vospAADGroup;
let loggedInUser = this.adalService.LoggedInUserEmail;

let graphUser2 = await graphClient.api("/users/" + loggedInUser + "/memberOf?").filter("id eq '" + aadGroupId + "'").get().catch(error => {return error});

Azure 上的插槽已配置为授予以下图形 API 范围:

Microsoft Graph (8) 
    Directory.AccessAsUser.all      Delegated       Access directory as the signed in user
    Directory.Read.all              Application     Read directory data
    Group.Read.All                  Delegated       Read all groups
    Group.Read.all                  Application     Read all groups
    User.Read                       Delegated       Sign in and read user profile
    User.Read.All                   Delegated       Read all users' full profiles
    User.Read.All                   Application     Read all users' full profiles
    User.ReadBasic.All              Delegated       Read all users' basic profiles

我对图形的调用因令牌观众而被拒绝。如何使用 ADAL.js 的 microsoft-adal-angular6 包装器为令牌指定正确的受众和范围?

使用 https://jwt.ms(感谢@TonyJu)我发现令牌受众正在引用我的应用程序的 clientId。所以在我的 JSON 中,我将端点节点引用更改为 “https://graph.microsoft.com": "https://graph.microsoft.com

这允许我的 http 拦截器从会话存储中获取端点的 "resource" 并为正确的受众获取令牌。

这似乎可以在 microsoft-adal-angular6 documentation 中使用一些说明。但也许这只是常识。

@NgModule({
imports: [
    MsAdalAngular6Module.forRoot({
      tenant: '<YOUR TENANT>',<-------------------------------- ADD
      clientId: '<YOUR CLIENT / APP ID>',<--------------------- ADD
      redirectUri: window.location.origin,
      endpoints: { <------------------------------------------- ADD
        "https://localhost/Api/": "xxx-bae6-4760-b434-xxx",
        ---
        ---
      },
      navigateToLoginRequestUrl: false,
      cacheLocation: '<localStorage / sessionStorage>', <------ ADD
    }),
    ---
    ---
  ],
  ---
  ---
})

Access token validation failure. Invalid audience

这个错误通常是由于听众不对造成的。我们可以使用 https://jwt.ms/ 来检查令牌中的观众。如果要调用Microsoft Graph API,资源应该是https://graph.microsoft.com.

参考:

https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens#payload-claims