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

Ris*_*abh 7 javascript azure-active-directory adal adal.js angular

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

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

this.context.getCachedToken(this.configService.AdalConfig.clientId)
Run Code Online (Sandbox Code Playgroud)

但是此方法返回的令牌与会话存储的令牌相同id_token (adal.idtoken)。它基本上是通过使用级联键在会话存储中创建一个新项目,其值与id_token

adal.access_token.key + clientId = id_token
Run Code Online (Sandbox Code Playgroud)

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

我也尝试access_tokenAuthenticationContext.acquireToken()方法来获取,但是它也给了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 + '/'
    };
  }
}
Run Code Online (Sandbox Code Playgroud)

辅助服务

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

Ris*_*abh 4

实际上,经过一番阅读后,发现将 SPA 连接到 Azure AD 需要 OAuth 2.0 隐式授予流程。微软文档说:

在此方案中,当用户登录时,JavaScript 前端使用适用于 JavaScript 的 Active Directory 身份验证库 (ADAL.JS) 和隐式授权从 Azure AD 获取 ID 令牌 (id_token)。该令牌被缓存,并且客户端在调用其 Web API 后端时将其作为不记名令牌附加到请求,该后端使用 OWIN 中间件进行保护。

因此,id_token我需要将其本身发送到后端 API,然后可以对其进行验证和使用。有关验证的更多信息如下

仅接收 id_token 不足以验证用户身份;您必须验证 id_token 的签名并根据应用程序的要求验证令牌中的声明。v2.0 端点使用 JSON Web 令牌 (JWT) 和公钥加密技术来签署令牌并验证它们是否有效。

您可以选择在客户端代码中验证 id_token,但常见做法是将 id_token 发送到后端服务器并在那里执行验证。验证 id_token 的签名后,您将需要验证一些声明。