access_token 在尝试使用 ADAL.js AuthenticationContext 获取访问令牌时与 id_token 相同?

access_token same as id_token when trying to acquire access token with ADAL.js AuthenticationContext?

我正在使用 Azure AD 验证我的单页应用程序 (Angular4),并使用 Adal.js 进行相同的验证。在登录页面上,我单击一个重定向到 Microsoft AAD 的按钮,成功登录后它重定向回应用程序主页,并从 JWT 接收 id_token 和用户信息。

我需要 access_token 用于后端 API 访问,我试图通过 ADAL AuthenticationContextgetCachedToken() 方法获取它,并发送作为参数的 clientId:

this.context.getCachedToken(this.configService.AdalConfig.clientId)

但是此方法 returns 存储在会话存储中的令牌与 id_token (adal.idtoken) 相同。它基本上通过一个连接键在会话存储中创建一个新项目,该键与 id_token

具有相同的值
adal.access_token.key + clientId = id_token

例如:adal.access_token.key239f6fc7-64d2-3t04-8gfd-501efc25adkd = <id-token-value>.

我也尝试使用 AuthenticationContext.acquireToken() 方法获取 access_token,但它也返回了 id_token

我哪里错了?

编辑:发布代码。 我正在调用函数 login(),并在成功登录后,尝试通过 get accessToken() 属性 访问器在 adal.config.ts.

中获取主页中的访问令牌

config.service.ts

import { Injectable } from '@angular/core';

@Injectable()
export class ConfigService {
  constructor() {}
  public get AdalConfig(): any {
    return {
      tenant: 'common',
      clientId: <application-id>,
      redirectUri: window.location.origin + '/',
      postLogoutRedirectUri: window.location.origin + '/'
    };
  }
}

adal.service.ts

import { ConfigService } from './config.service';
import { Injectable } from '@angular/core';
import { adal } from 'adal-angular';
let createAuthContextFn: adal.AuthenticationContextStatic = AuthenticationContext;

@Injectable()
export class AdalService {
  private context: adal.AuthenticationContext;
  constructor(private configService: ConfigService) {
    this.context = new createAuthContextFn(configService.AdalConfig);
  }

  login() {
    this.context.login();
  }

  logout() {
    this.context.logOut();
  }

  handleCallback() {
    this.context.handleWindowCallback();
  }

  public get userInfo() {
    return this.context.getCachedUser();
  }

  public get accessToken() {
    return this.context.getCachedToken(this.configService.AdalConfig.clientId);
    // return this.context.acquireToken(this.configService.AdalConfig.clientId, function(message, token, response) {
    //   console.log(message, token, response);
    // });
  }

  public get isAuthenticated() {
    return this.userInfo && this.accessToken;
  }
}

实际上,经过一些阅读后发现,将 SPA 连接到 Azure AD 需要 OAuth 2.0 隐式授权流程。 Microsoft documentation 表示:

In this scenario, when the user signs in, the JavaScript front end uses Active Directory Authentication Library for JavaScript (ADAL.JS) and the implicit authorization grant to obtain an ID token (id_token) from Azure AD. The token is cached and the client attaches it to the request as the bearer token when making calls to its Web API back end, which is secured using the OWIN middleware.

因此,我需要将 id_token 本身发送到后端 API,进而可以验证和使用它。提供了有关验证的更多信息 here:

Just receiving an id_token is not sufficient to authenticate the user; you must validate the id_token's signature and verify the claims in the token per your app's requirements. The v2.0 endpoint uses JSON Web Tokens (JWTs) and public key cryptography to sign tokens and verify that they are valid.

You can choose to validate the id_token in client code, but a common practice is to send the id_token to a backend server and perform the validation there. Once you've validated the signature of the id_token, there are a few claims you will be required to verify.

当我尝试将令牌发送到 .Net Core API 端点时,我遇到了像您这样的问题。 当我从 sessionStorage 上的 adal.access.token.key 节点发送令牌时,它对我有用。

使用 adal.access.token.keyadal.idtoken 标记值(它们相同)不适用于我.

Valid token on adal.access.token.key node.