使用 Active Directory 令牌从 Angular 到 Web API 应用程序进行安全 API 调用

Posted

技术标签:

【中文标题】使用 Active Directory 令牌从 Angular 到 Web API 应用程序进行安全 API 调用【英文标题】:Making Secure API Call from Angular to Web API application using Active Directory Token 【发布时间】:2021-10-04 15:39:39 【问题描述】:

我在尝试从 Angular 安全调用 Web api 端点时收到 401 错误。我通过 Active Directory / MSAL 获得了承载令牌的身份验证。我在下面的代码中从 testAPI1() 方法调用 API...

import  Component, OnInit  from '@angular/core';
import  MsalService  from '@azure/msal-angular';
import  AuthenticationResult  from '@azure/msal-common';
import  HttpClient, HttpHeaders  from '@angular/common/http';
import  BehaviorSubject, Observable  from 'rxjs';

 @Component(
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.scss']
 )

export class AppComponent implements OnInit

  title = 'HandHeldClientADAuth';
  isAuthenticated = false;
  token: string = "";
  idToken: string = "";
  tokenType: string = "";
  idTokenClaims: string = "";
  authority: string = "";
  state: string | undefined = "";
  expiresOn: Date | null = new Date();
  uniqueId: string = "";
  username: string | undefined;

 constructor(private msalServices: MsalService, private http: HttpClient,)
 
 

ngOnInit()
this.msalServices.instance.handleRedirectPromise().then(
  res => 
    if(res!=null && res.accessToken !=null)
      this.msalServices.instance.setActiveAccount(res.account);
      this.token = res.accessToken;
      this.authority = res.authority;
      this.idToken = res.idToken;
      var idTokenClaims = res.idTokenClaims;
      this.tokenType = res.tokenType;
      this.state = res.state;
      this.expiresOn = res.expiresOn;
      this.uniqueId = res.uniqueId;
      this.username = res.account?.username;

      console.log("TokenClaims ::"+idTokenClaims);

    
  
 )


isLoggedIn(): boolean
 return this.msalServices.instance.getActiveAccount() != null


loginRedirect()
 this.msalServices.loginRedirect();


logout()
 this.msalServices.logout();


testAPI1()
    var t2 = this.token;
    const myheaders = new HttpHeaders(
        'Content-Type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer '+ this.token,
        'Access-Control-Allow-Origin':'*'
    );

 console.log("calling Web APIs App 'GetSecureMessage' API ...");
 this.http.get('https://localhost:44362/v2/Site/GetSecureMessage', headers: myheaders)
    .subscribe((data)=>
        console.warn(data);
    )
 

【问题讨论】:

https 不适用于本地主机 我猜你已经这样做了,但是将 console.log("calling Web APIs App 'GetSecureMessage' API ...") 更改为 console.log("calling Web APIs App 'GetSecureMessage' API .. . - 令牌”, this.token );并在调用 testAPI1() 时查看 this.token 中是否真的有价值。 我确实有令牌,可以在调试中看到... 另一次尝试:尝试使用:'Content-Type': 'application/json; 'Authorization':Bearer $this.token,(注意:我将作为答案,因为这里显示不好)。 401错误意味着未经授权,所以首先,如果您删除了[Authorize]属性,您的请求可以到达api吗?如果可以,请检查承载令牌是否具有正确的 scp cliam 代表权限或角色声明应用程序权限(正如您在问题中提到的,这里应该是一个代表权限令牌)。只需解码 jwt 令牌。 【参考方案1】:

再试一次。尝试一下:


   const myheaders = new HttpHeaders(
        'Content-Type': 'application/json,
        'Authorization': `Bearer $this.token`,
   );

如果不起作用,请尝试直接修改ANGULAR INTERCEPTOR中的API调用,如我所述HERE

如果这些解决方案都不起作用,则可能是授权部分存在问题,而不是 HTTP 调用。

【讨论】:

我运气不好...我正在使用 Hotmail 电子邮件地址从 AD 获取令牌,其中 AD 将 Web API 应用程序注册为单租户...这有什么不同吗?我还注册了 web api 和客户端的多租户应用程序作为尝试替代但没有运气。在这种方法中,如果我在 AD 上将应用程序注册为多租户

以上是关于使用 Active Directory 令牌从 Angular 到 Web API 应用程序进行安全 API 调用的主要内容,如果未能解决你的问题,请参考以下文章

您如何从 Azure Active Directory 中获取搭建的 Weather Forecast Api 将接受的访问令牌?

从 Azure Active Directory 验证 JWT

使用 Azure Active Directory 客户端凭据流控制身份验证令牌的到期

如何使用 Active Directory 存储在 AcquireTokenAsync 中收到的令牌

使用 azure-cli 访问 Azure Active Directory 的令牌

Azure Active Directory,允许的令牌受众似乎没有做任何事情