Angular 5 在 CORS 中调用 Azure AD 保护的 Web API 结果
Angular 5 call AzureAD protected WebAPI results in CORS
环境
- Angular 5 个前端
- ASP.NET WebAPI 2
- WebAPI 上的 AzureAD 身份验证
配置
- WebAPI 已为所有人启用 CORS (***)
- AzureAD 已启用 OAuthImplicitFlow
- Angular 和 WebAPI 托管在相同的 IIS 中,不同的端口
挑战
当直接通过浏览器调用 WebAPI 时,AzureAD 身份验证工作正常并且调用获得授权。然而,当 Angular 调用 WebAPI 时,AzureAD 的身份验证挑战会引发 CORS 问题。
Angular 应用程序 不会 直接调用 Azure(通过 adal-angular),它应该只能通过 WebAPI 调用。
Angular 应用成功调用了 WebAPI 上不受保护的 GET/POST 函数,因此 Angular-WebAPI 连接正常。
(更新 1 Angular APP 调用 ADAL-ANGULAR 向 Azure 进行身份验证并获取令牌,然后相同的令牌是作为承载传递给 WebAPI)
想知道我在这里遗漏了什么吗?可以根据需要提供任何特定的 code/configuration。
代码
WebAPI
[HttpGet]
[Authorize]
[Route(ApiEndPoint.AzureAD.GetMyProfile)]
public async Task<ADUser> GetUserProfile()
{
ADUser user = null;
GraphFacade graphFacade = new GraphFacade(this.graphServiceClient);
user = await graphFacade.GetMyProfileDetails();
return user;
}
Angular
Authenticate(): Observable<any> {
this.authServerUrl = "https://localhost:44371/"; // This is where WebAPI is running
let httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) };
let authRequest = this._http.get<any>(this.authServerUrl + '/api/aduser/profile', httpOptions);
return authRequest;
}
错误信息
Failed to load
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=fba45f7b
: Response to preflight request doesn't pass access
control check: No 'Access-Control-Allow-Origin' header is present on
the requested resource. Origin 'null' is therefore not allowed access.
这不是它的工作原理。 Http 客户端 永远不会将您重定向 到页面(在您的情况下是 AAD Signin-Page)。它仅从/向资源检索/发送内容。您可以使用 window.location.replace() 执行重定向,但这可能不是您想要的(令牌不会返回到您的 angular 应用程序)。
您需要选择 Active Directory 身份验证库,例如 adal-js 或 MSAL(您会发现两者的 Angular NPM 包)并使用您的 AAD 设置配置组件。然后你可以从你的 Angular 客户端挑战登录并为你的 API 请求一个 access_token。现在你必须在授权 HTTP Header 中传递 access_token 以及你针对你的(保护)API.
发出的每个请求
请注意,您应该在 AAD 中创建另一个代表您的 Angular UI 的应用程序,并授予该应用程序对您的 API.
的访问权限
对于那些查看 msal-angular MsalHttpInterceptor.
的人
我自己实现了 MsalInterceptor 来克服 protectedResourceMap 的问题。
这是我的自定义代码块:
// #region own workaround in order not to put every api endpoint url to settings
if (!scopes && req.url.startsWith(this.settingsService.apiUrl)) {
scopes = [this.auth.getCurrentConfiguration().auth.clientId];
}
// #endregion
// If there are no scopes set for this request, do nothing.
if (!scopes) {
return next.handle(req);
}
PS: 为 protectedResourceMap 中的通配符投票 https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1776
环境
- Angular 5 个前端
- ASP.NET WebAPI 2
- WebAPI 上的 AzureAD 身份验证
配置
- WebAPI 已为所有人启用 CORS (***)
- AzureAD 已启用 OAuthImplicitFlow
- Angular 和 WebAPI 托管在相同的 IIS 中,不同的端口
挑战
当直接通过浏览器调用 WebAPI 时,AzureAD 身份验证工作正常并且调用获得授权。然而,当 Angular 调用 WebAPI 时,AzureAD 的身份验证挑战会引发 CORS 问题。
Angular 应用程序 不会 直接调用 Azure(通过 adal-angular),它应该只能通过 WebAPI 调用。 Angular 应用成功调用了 WebAPI 上不受保护的 GET/POST 函数,因此 Angular-WebAPI 连接正常。
(更新 1 Angular APP 调用 ADAL-ANGULAR 向 Azure 进行身份验证并获取令牌,然后相同的令牌是作为承载传递给 WebAPI)
想知道我在这里遗漏了什么吗?可以根据需要提供任何特定的 code/configuration。
代码
WebAPI
[HttpGet]
[Authorize]
[Route(ApiEndPoint.AzureAD.GetMyProfile)]
public async Task<ADUser> GetUserProfile()
{
ADUser user = null;
GraphFacade graphFacade = new GraphFacade(this.graphServiceClient);
user = await graphFacade.GetMyProfileDetails();
return user;
}
Angular
Authenticate(): Observable<any> {
this.authServerUrl = "https://localhost:44371/"; // This is where WebAPI is running
let httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) };
let authRequest = this._http.get<any>(this.authServerUrl + '/api/aduser/profile', httpOptions);
return authRequest;
}
错误信息
Failed to load https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=fba45f7b : Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
这不是它的工作原理。 Http 客户端 永远不会将您重定向 到页面(在您的情况下是 AAD Signin-Page)。它仅从/向资源检索/发送内容。您可以使用 window.location.replace() 执行重定向,但这可能不是您想要的(令牌不会返回到您的 angular 应用程序)。
您需要选择 Active Directory 身份验证库,例如 adal-js 或 MSAL(您会发现两者的 Angular NPM 包)并使用您的 AAD 设置配置组件。然后你可以从你的 Angular 客户端挑战登录并为你的 API 请求一个 access_token。现在你必须在授权 HTTP Header 中传递 access_token 以及你针对你的(保护)API.
发出的每个请求请注意,您应该在 AAD 中创建另一个代表您的 Angular UI 的应用程序,并授予该应用程序对您的 API.
的访问权限对于那些查看 msal-angular MsalHttpInterceptor.
的人
我自己实现了 MsalInterceptor 来克服 protectedResourceMap 的问题。
这是我的自定义代码块:
// #region own workaround in order not to put every api endpoint url to settings
if (!scopes && req.url.startsWith(this.settingsService.apiUrl)) {
scopes = [this.auth.getCurrentConfiguration().auth.clientId];
}
// #endregion
// If there are no scopes set for this request, do nothing.
if (!scopes) {
return next.handle(req);
}
PS: 为 protectedResourceMap 中的通配符投票 https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1776