Angular 2 SPA Azure Active Directory JWT问题

时间:2017-03-07 12:47:16

标签: angular azure-active-directory adal.js

想知道是否有任何Azure Active Directory / Angular 2 / Adal专家可以为此提供帮助。

我的设置如下:Azure Active Directory有三个应用程序注册。一个用于Web API,一个用于WPF应用程序,一个用于Angular 2应用程序。

Web API的配置看起来相当标准:

<add key="ida:Tenant" value="<tenant>" />
<add key="ida:Audience" value="<ResourceURI>" />

WPF应用程序(正在运行)的配置是

<add key="ida:AADInstance" value="https://login.windows.net/{0}"/>
<add key="ida:Tenant" value="<tenant>" />
<add key="ida:RedirectUri" value="<some redirect>" />
<add key="ida:ClientId" value="<client id as configured in Azure>" />
<add key="ApiResourceId" value="<The WEB API resource URI>"/>
<add key="ApiBaseAddress" value="<The base address of the Web API>"/>

这是带有NG2-ADAL和ADAL.js的Angular 2配置

   public get adalConfig(): any {


    return {
      instance: 'https://login.windows.net/',
      tenant: '<tenant>',
      clientId: '<client id configured for Angular App in Azure AD>',
      redirectUri: '<Angular 2 app Url>',
      extraQueryParameter: 'nux=1',
      postLogoutRedirectUri: '<Angular 2 app Url>',
      cacheLocation: 'localStorage',
      loginResource: '<Web API Resource Uri>',


    };

angular和WPF都能够在AAD中登录并获得令牌。

问题在于Angular 2应用程序。

WPF应用程序(可以正常工作)可以正确登录Azure Active Directory,Web API应用程序接受JWT(令牌),并且可以成功调用其余服务。

当WPF应用程序通过microsoft.online.com/xxxxxxx登录时,它会提供一个令牌,其中包含如下声明:

 Header
{
  typ: "JWT",
  alg: "RS256",
  x5t: "_UgqXG_tMLduSJ1T8caHxU7cOtc",
  kid: "_UgqXG_tMLduSJ1T8caHxU7cOtc"
}
 Payload
{
  aud: "<web api resource uri>",
  iss: "https://sts.windows.net/1afea43f-3f0b-4a86-ad29-d444b80d2c91/",
  iat: 1488889876,
  nbf: 1488889876,
  exp: 1488893776,
  acr: "1",
  aio: "NA",
  amr: [
    "pwd"
  ]
}

对于这个 - aud参数是Web API资源URI。它完美地运作

我正在使用ng2-adal,它是Angular 2的adal.js的包装器。所以当Angular 2应用程序登录时会收到一个类似这样的标记:

 Header
{
  typ: "JWT",
  alg: "RS256",
  x5t: "_UgqXG_tMLduSJ1T8caHxU7cOtc",
  kid: "_UgqXG_tMLduSJ1T8caHxU7cOtc"
}
 Payload
{
  aud: "<angular app client id>",
  iss: "https://sts.windows.net/1afea43f-3f0b-4a86-ad29-d444b80d2c91/",
  iat: 1488888955,
  nbf: 1488888955,
  exp: 1488892855,
  amr: [
    "pwd"
  ]

}

因此主要区别 - ,我认为为什么我收到错误是WPF应用程序令牌中的 aud参数包含正确的受众并且正在被接受,而Angular Application从其令牌中返回客户端ID,该令牌与Web Api中的资源URI 不匹配,因此给出了401错误 - 此请求的授权被拒绝

是否有人知道如何配置NG2-ADAL(adal.js)以获取Azure活动目录以在JWT的aud参数中发出包含资源URI的令牌?

我已尝试过loginResource参数和端点集合,但没有运气。

非常感谢...

3 个答案:

答案 0 :(得分:3)

好的,所以我设法解决了这个问题。基本上解决方案如下:

Angular 2应用程序必须使用其配置的客户端ID来使用AAD进行主要身份验证。

所以它的配置是

tenant: '<tenant>',
clientId: '<configured angular 2 client id', 
redirectUri: 'some redirect',
postLogoutRedirectUri: 'some redirect',
cacheLocation: 'localStorage'

这不起作用的原因是,一旦Angular Client成功登录,它就会尝试使用此令牌来访问web api(这是重要的一点)是不同的机

为了解决这个问题,我在ng2-adal上调用了函数acquireToken,如下所示:

this.adalService.acquireToken(<client id of target web api>).subscribe(p=>{
       console.log("Acquired token = " + p);

       let headers = new Headers();
        headers.append("Authorization", "Bearer " + p);
        someService.testWebApi(headers).subscribe(res => {
        console.log(res);
      }, (error) => {
        console.log(error);
      });


    }, (error => {
      console.log(error);
    }));

然后服务电话工作.. 所以基本上我的情况是我试图在另一台机器上对另一个web api进行CORS调用,因此我登录的令牌不允许在另一台机器上进行web api调用。

我已经读过,更有效的方法是将它存储在配置的端点集合中,这样当为远程机器调用uri时,会拾取正确的资源端点,但我无法让这个工作。我希望这有助于某人。

答案 1 :(得分:1)

实际上,audpayload的值应该是Azure AD应用程序的客户端ID,您的ng2应用程序将从该客户端ID获取访问令牌。因此,如果Azure上的Web API应用程序受此AzureAD应用程序的保护,则来自ng2的访问令牌应该能够针对您的Web API授权请求调用。

我快速测试NG2 ADAL sample,使用最简单的配置如下:

{
  tenant: '<tenant id>',
  clientId: '<azure ad application client id>', // also use this application to protect the backed services
  redirectUri: window.location.origin + '/',
  postLogoutRedirectUri: window.location.origin + '/'
}

它在我身边很好用。

请仔细检查您的配置,然后重试。

答案 2 :(得分:1)

我遇到了同样的问题。在端点中,我放置了APP URI ID,将其替换为App ID。

var endpoints = {

    // Map the location of a request to an API to a the identifier of the associated resource
    "https://localhost:44327/": "<Application ID>" // Not APP URI ID
 };

还为Web API启用了CORS。 遵循:https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api