azure 使用idToken交换AccessToken(MSAL)

lmyy7pcs  于 2023-06-24  发布在  其他
关注(0)|答案(1)|浏览(160)

我在Angular 16前端应用程序中使用MSAL 3验证从Microsoft接收的AccessToken时遇到了一个问题。虽然我可以成功地获得令牌,但在验证AccessToken时遇到了一些问题。奇怪的是,我可以毫无问题地验证idToken,但AccessToken似乎无效,即使在jwt.io上检查也是如此。
为了解决这个问题,我实现了一个自定义HTTP拦截器,它利用msal.instance.silentAcquire(...)来检索idToken并使用该令牌创建一个新的HTTP头。虽然这种方法有效,但它并不干净,并导致代码混乱。
我将感谢任何见解或解释,为什么我无法验证AccessToken。
提前感谢您的帮助!
为了更好的理解:Angular Frontend通过MSAL获取Token,使用Token调用Spring Boot API,后端验证Token并在Token有效时给出响应。

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpErrorResponse,
  HttpStatusCode,
} from '@angular/common/http';
import { Observable, catchError, from, mergeMap, throwError } from 'rxjs';
import { MsalService } from '@azure/msal-angular';
import { SilentRequest } from '@azure/msal-browser';

@Injectable()
export class HttpInterceptor implements HttpInterceptor {

  constructor(private authService: MsalService) { }

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {

    if (request.url.includes('localhost:8080')) {
      const headerConf = {
        Authorization: '',
        'Content-Type': 'application/json',
        Accept: 'application/json',
      };

      const silentRequest: SilentRequest = {
        scopes: ['user.read'],
      };

      return from(this.authService.instance.acquireTokenSilent(silentRequest)).pipe(
        mergeMap((data) => {
          const idToken = data.idToken;
          headerConf.Authorization = `Bearer ${idToken}`;
          const req = request.clone({ setHeaders: headerConf });
          return next.handle(req);
        }),
        catchError((err) => {
          const error = err as HttpErrorResponse;
          if (error.status == HttpStatusCode.Forbidden) {
            console.error("Fehler beim request", error);
          }
          return throwError(() => new Error(err));
        })
      );
    } else {
      return next.handle(request);
    }
  }
}

在www.example.com上验证AccessToken,在azure中创建了一个api暴露,在spring boot中尝试了几个密钥和颁发者配置jwt.io, created an api expose in azure, tried several key and issuer configs in spring boot

csga3l58

csga3l581#

我创建了一个Azure AD应用程序并授予API权限,如下所示:

我通过Postman使用以下参数生成了访问和ID令牌

https://login.microsoftonline.com/TenantID/oauth2/v2.0/token

client_id:ClientID
grant_type:authorization_code
scope:user.read profile openid
code:code
redirect_uri:https://jwt.ms
client_secret:ClientSecret

ID令牌验证成功,如下所示:

但是访问令牌dint get validated并得到如下错误:

出现“invalid token”错误的原因有很多,比如访问令牌过期、传递错误的作用域、aud无效等。

  • 每当访问令牌即将到期时,MSAL都会处理令牌的刷新。刷新令牌存储在缓存中。

强制应用程序定期获取新的访问令牌,并将值设置为true

result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
             .WithForceRefresh(true)
             .ExecuteAsync();

请参阅我的SO Thread以了解更多细节。

注意:如果要为Microsoft Graph生成访问令牌,则无需验证访问令牌。

  • 不需要验证“您的”APIS的访问令牌,就像为MS Graph API颁发的那样。
  • 为Graph颁发的访问令牌只能用于访问Microsoft Graph。
  • 您可以验证自己的Web API。

我生成了Web API访问令牌

scope: api://xxxx/test.read

现在,访问令牌验证成功如下:

相关问题