[英]Angular 2 SPA Azure Active Directory JWT Issue
Wondering if any Azure Active Directory/Angular 2/Adal experts can assist with this. 想知道是否有任何Azure Active Directory / Angular 2 / Adal专家可以提供帮助。
My set up is as follows: Azure Active Directory with three app registrations. 我的设置如下:Azure Active Directory有三个应用程序注册。 One for the Web API, one for a WPF application and one for an Angular 2 Application.
一个用于Web API,一个用于WPF应用程序,一个用于Angular 2应用程序。
The configuration for the Web API looks fairly standard: Web API的配置看起来相当标准:
<add key="ida:Tenant" value="<tenant>" />
<add key="ida:Audience" value="<ResourceURI>" />
The configuration for the WPF application (which is working) is 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>"/>
Here is the Angular 2 configuration with NG2-ADAL and ADAL.js 这是带有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>',
};
Both angular and WPF are able to login in AAD and get a token. angular和WPF都能够在AAD中登录并获得令牌。
The problem lies with the Angular 2 Application. 问题在于Angular 2应用程序。
The WPF application (which works) can login to Azure Active Directory correctly and the JWT (token) is accepted by the Web API application and the rest service can be called successfully. WPF应用程序(可以正常工作)可以正确登录Azure Active Directory,Web API应用程序接受JWT(令牌),可以成功调用其余服务。
When the WPF application logs in via microsoft.online.com/xxxxxxx it supplies a token which includes a claim like this: 当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"
]
}
And for this one - the aud parameter is the Web API resource URI. 对于这一个 - aud参数是Web API资源URI。 and it works perfectly
它完美无缺
I am using ng2-adal which is a wrapper around adal.js for Angular 2. So when the Angular 2 Application Logs in it receives a token which looks like this: 我正在使用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"
]
}
So the main difference - and I think why I am getting the error is that the aud parameter in the token for the WPF application contains the correct audience and is being accepted, whereas the Angular Application is returning the Client ID from its token which does not match the Resource URI from the Web Api and hence is giving me a 401 error - Authorization has been denied for this request 所以主要区别 - 我认为我收到错误的原因是WPF应用程序的令牌中的aud参数包含正确的受众并且正被接受,而Angular应用程序从其令牌中返回客户端ID而不是匹配来自Web Api 的资源URI ,因此给出了401错误 - 此请求的授权被拒绝
Does anyone know how to configure the NG2-ADAL (adal.js) to get Azure active directory to issue a token which contains the Resource URI in the aud parameter of the JWT? 有谁知道如何配置NG2-ADAL(adal.js)以获取Azure活动目录以发出包含JWT的aud参数中的资源URI的令牌?
I have tried the loginResource parameter and the endpoints collection but with no luck. 我已经尝试了loginResource参数和端点集合,但没有运气。
Many Thanks... 非常感谢...
Ok, so I have managed to solve this. 好的,所以我设法解决了这个问题。 Basically the solution is the following:
基本上解决方案如下:
The Angular 2 application must use its configured client id to do the primary authentication with AAD. Angular 2应用程序必须使用其配置的客户端ID来使用AAD进行主要身份验证。
So its config is 所以它的配置是
tenant: '<tenant>',
clientId: '<configured angular 2 client id',
redirectUri: 'some redirect',
postLogoutRedirectUri: 'some redirect',
cacheLocation: 'localStorage'
And the reason this wasn't working is that once the Angular Client has logged in successfully, it was trying to use this token to access a web api which (and this is the important bit) was on a different machine . 而这个问题无法解决的问题是,一旦Angular Client成功登录,就会尝试使用此令牌来访问web api(这是重要的一点)是在另一台机器上 。
To solve this I called the function acquireToken on the ng2-adal like this: 为了解决这个问题,我在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);
}));
and then the service call worked.. So basically my scenario was that I was trying to do a CORS call to another web api on another machine and hence the token I got to login was not being allowed for making a web api call on another machine. 然后服务调用工作..所以基本上我的情况是我试图在另一台机器上对另一个web api进行CORS调用,因此我登录的令牌不允许在另一台机器上进行web api调用。
I have read that a more efficient way of doing this is to store it in the endpoints collection of the config so that when the uri is called for your remote machine, the correct resource endpoint is picked up, but I was unable to get this to work. 我已经读过这样做的一种更有效的方法是将它存储在配置的端点集合中,以便在为远程计算机调用uri时,会选择正确的资源端点,但我无法将其转换为工作。 I hope this helps someone.
我希望这可以帮助别人。
Actually, the value of aud
in payload
should be the Azure AD application's client ID, which your ng2 application acquire access token from. 实际上,
payload
的aud
值应该是Azure AD应用程序的客户机ID,您的ng2应用程序将从该客户机ID获取访问令牌。 So, if your Web API application on Azure is protected by this AzureAD application, the access token get from ng2 should be able to authorize the request calls against to your Web API. 因此,如果Azure上的Web API应用程序受此AzureAD应用程序的保护,则来自ng2的访问令牌应该能够针对您的Web API授权请求调用。
I have a quick test leverage the NG2 ADAL sample , use the simplest configuration as following: 我有一个快速测试利用NG2 ADAL样本 ,使用如下最简单的配置:
{
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 + '/'
}
It works fine on my side. 它在我身边很好用。
Please double check your configurations and try again. 请仔细检查您的配置,然后重试。
I had the same problem. 我有同样的问题。 In endpoints I had put APP URI ID, replaced it with App ID.
在端点中,我放置了APP URI ID,将其替换为App ID。
var endpoints = { 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
};
Also enabled CORS for Web API. 还启用了CORS for Web API。 Followed this: https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
遵循这个: https : //docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.