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

7
我正在使用Adal.js对我的单页应用程序(Angular4)进行Azure AD身份验证。在登录页面上,我点击一个按钮,重定向到Microsoft AAD,并在成功登录后重定向回应用程序主页,从JWT接收id_token和用户信息。
我需要access_token以访问后端API。我尝试通过ADAL的AuthenticationContextgetCachedToken()方法获取它,并将clientId作为参数发送:
this.context.getCachedToken(this.configService.AdalConfig.clientId)

但是这种方法返回的仍然是存储在会话存储中的同一个令牌,即 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(),成功登录后,通过adal.config.ts中的get accessToken()属性访问器,在主页上尝试获取访问令牌。

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;
  }
}

你应该发布你的完整身份验证代码... - Shawn Tabrizi
为了进行身份验证,我只需创建一个包含所有必要信息(如“租户”、“客户端ID”、“重定向URI”等)的“AdalConfig”对象,然后使用该“AdalConfig”初始化一个新的“AuthenticationContext”,并使用初始化的上下文方法。我已经发布了方法调用。请告诉我还需要什么。 - Rishabh
你在哪里指定要调用的资源?你需要发布你的代码,否则没有人能够帮助你。 - Shawn Tabrizi
发布了 config.service.tsadal.service.ts 代码,这是我在其中指定所有AAD所需信息的地方。希望这能有所帮助 :) - Rishabh
2
我认为Shawn在正确的轨道上 :) 我以前在使用ADAL.JS时也遇到了类似的问题,当时我不知何故错误地指定了资源,导致它得到了一个令牌(id令牌)。 - juunas
2个回答

4
实际上,经过一些阅读,发现将SPA连接到Azure AD需要OAuth 2.0 Implicit Grant流程。 Microsoft文档表示:
在这种情况下,当用户登录时,JavaScript前端使用Active Directory Authentication Library for JavaScript (ADAL.JS)和隐式授权许可来从Azure AD获取ID令牌(id_token)。令牌被缓存,客户端在调用其Web API后端时将其作为承载令牌附加到请求中,该后端由OWIN中间件进行安全保护。
因此,我需要发送id_token本身到后端API,然后可以进行验证和使用。有关验证的更多信息请参见此处
仅接收id_token是不足以验证用户身份的;您必须根据应用程序的要求验证id_token的签名并验证令牌中的声明。v2.0端点使用JSON Web Tokens(JWT)和公钥加密来签署令牌并验证它们是否有效。您可以选择在客户端代码中验证id_token,但常见做法是将id_token发送到后端服务器并在那里执行验证。一旦您验证了id_token的签名,就需要验证一些声明。

1
你成功使用ADAL从ID Token中获取访问令牌了吗? - looooongname
我正在遵循同样的方法,但调用图形 API 返回错误: "error": { "code": "InvalidAuthenticationToken", "message": "访问令牌验证失败。无效的受众。", "innerError": { "request-id": "", "date": "" } } - Mudasar Rauf

0
我在尝试将令牌发送到 .Net Core API 端点时遇到了与您类似的问题。 当我从 sessionStorage 的 adal.access.token.key 节点发送令牌时,它对我起作用了。
但是,使用 adal.access.token.key 或 adal.idtoken 令牌值(它们是相同的)对我来说并没有起作用。 在 adal.access.token.key 节点上的有效令牌。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接