NitinSingh
NitinSingh

Reputation: 2068

Angular 5 call AzureAD protected WebAPI results in CORS

Environment

Configuration

Challenge

When WebAPI is called directly via browser, AzureAD auth challenge works fine and call gets authorized. However when Angular calls the WebAPI, AzureAD's auth challenge throws a CORS issue.

The Angular app will not call Azure directly (via adal-angular), its supposed to call via WebAPI only. Angular app is successfully calling non-protected GET/POST functions on WebAPI successfully, so Angular-WebAPI connectivity is fine.

(Update 1 Angular APP calls ADAL-ANGULAR to authenticate with Azure and get a token, then same token is passed as bearer to WebAPI)

Any thoughts what I am missing out here ? Any specific code/configuration can be made available as required.

Code

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

Error Message

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.

Upvotes: 5

Views: 1914

Answers (2)

Cyclion
Cyclion

Reputation: 774

For those who looks about msal-angular MsalHttpInterceptor.
I've made own implementation of MsalInterceptor to overcome issues with protectedResourceMap.
This is my custom code block:

// #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: Vote for wildcard in protectedResourceMap https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1776

Upvotes: 0

Martin Brandl
Martin Brandl

Reputation: 58931

This is not how it works. The Http Client will never redirect you to a page (in your case the AAD Signin-Page). It only retrieves / sends content from / to a resource. You can perform a redirect using window.location.replace() but thats probably not what you want (the token will not get back to your angular application).

You need to choose a Active Directory Authentication Library like adal-js or MSAL (you will find Angular NPM packages for both) and configure the component with your AAD settings. Then you can challange the signin from your Angular client and request an access_token for your API. Now you have to pass the access_token in the Authorization HTTP Header with each request you make against your (protect) API.

Note that you should create another Application in the AAD that represents your Angular UI and grant that app access to your API.

Upvotes: 3

Related Questions