Angular 5调用AzureAD保护的WebAPI结果为CORS

时间:2018-05-29 06:42:15

标签: angular azure cors asp.net-web-api2 azure-active-directory

环境

  • Angular 5前端
  • ASP.NET WebAPI 2
  • WebAPI上的AzureAD身份验证

配置

  • WebAPI为每个人启用了CORS(***)
  • AzureAD是OAuthImplicitFlow已启用
  • Angular和WebAPI托管在同一个IIS,不同的端口

挑战

当通过浏览器直接调用WebAPI时,AzureAD auth challenge工作正常,并且呼叫获得授权。但是当Angular调用WebAPI时,AzureAD的auth挑战会引发CORS问题。

Angular应用不会直接调用Azure(通过adal-angular),它只能通过WebAPI调用。 Angular app成功地在WebAPI上成功调用了不受保护的GET / POST函数,因此Angular-WebAPI连接正常。

更新1 Angular APP调用ADAL-ANGULAR以通过Azure进行身份验证并获取令牌,然后将相同的令牌作为承载传递给WebAPI

有什么想法,我在这里错过了什么?可以根据需要提供任何特定的代码/配置。

代码

的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;
    }

  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;
  }

错误消息

  

无法加载   https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=fba45f7b   :对预检请求的响应没有通过访问   控制检查:No&#39; Access-Control-Allow-Origin&#39;标题存在于   请求的资源。起源&#39; null&#39;因此不允许访问。

2 个答案:

答案 0 :(得分:2)

这不是它的工作原理。 Http客户端永远不会将您重定向到一个页面(在您的情况下是AAD Signin-Page)。它仅从/向资源检索/发送内容。您可以使用 window.location.replace()执行重定向,但这可能不是您想要的(令牌不会返回到您的角应用程序)。

您需要选择 Active Directory身份验证库,例如 adal-js MSAL (您将找到两者的Angular NPM包)和使用AAD设置配置组件。然后,您可以挑选Angular客户端的登录信息,并为您的API请求 access_token 。现在,您必须使用针对(保护)API的每个请求传递Authorization HTTP Header中的access_token。

请注意,您应该在AAD中创建另一个代表Angular UI的应用程序,并授予该应用程序访问您的API的权限。

答案 1 :(得分:0)

对于那些了解msal角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

中的通配符投票