11

I have implemented Token based authentication in AngularJS, however my security api (which generates token) is windows based to centralize all AD interaction to one site.

The structure is as follows: enter image description here

The flow is as follows:

  1. User is not logged in
  2. $http request to windows authenticated Security Api is made
  3. Security Api users AD to create token (authentication handled by windows auth)
  4. Token returned to app
  5. All subsequent requests use token to token authenticated apis

This all works fine when the security and app were on the same domain, however as soon as the $http request needs to go across the domain, no Authorization header with windows credentials is sent causing a 401.

Example Request (api is windows authenticated)

enter image description here

Security Api allows cross domain requests by allowing Origin's (* is only for testing not production):

<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />

Question (TL:DR):

Is it possible, and if so, how do you get the AngularJS client app to passthrough the windows credentials when making a cross domain $http request?

Oliver
  • 35,233
  • 12
  • 66
  • 78

2 Answers2

15

Try setting the withCredentials property to true when making the AJAX request to ensure that the client will send its credentials:

$http.get(url, { withCredentials: true, ...})

Basically what this flag will do is to set the withCredentials property on the underlying XMLHttpRequest native object.

Also you might need to include the Authorization header on the server to the Access-Control-Allow-Headers response.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 1
    Worked exactly as expected, this is what I was looking for! – Oliver Mar 04 '14 at 08:24
  • 2
    To future users, you need to set the following on your web.config side to allow this: – Oliver Mar 04 '14 at 08:34
  • 1
    @Darin: What would the Authorization header be populated with? (Or, how would we get that content?). I see that when setting withCredentials, it adds a WWW-Authenticate header - which gets past the 401, to give a blank response. (This is with CORS set up to '*' allowed for origin, methods and headers) – Overflew Aug 25 '15 at 06:59
  • Ah - In my case I needed to add 'SupportsCredentials = true'. Ie. In the WebApiConfig: new EnableCorsAttribute("*", "*", "*") { SupportsCredentials = true }; – Overflew Aug 26 '15 at 05:29
  • 2
    After adding withCredentials:true, it gives me a popup, is there any way to do this without the popup.. – Prafful Garg May 12 '16 at 14:16
2

My project is an Angular2-rc4 app calling a .NET Core 1.0.0 WebAPI cross domain. Adding to this answer in case it may help others.

I also posted this on this thread.

As mentioned by others, pass withCredentials true:

getUser() {
    return this.http.get(this._apiUrl + "/account/GetUser", { withCredentials: true })
        .toPromise()
        .then(response => response.json().data)
        .catch(this.handleError);
}

In your WebAPI project you can set CORS policies in Startup.cs (instead of web.config):

public void ConfigureServices(IServiceCollection services)
{
    var corsBuilder = new CorsPolicyBuilder();
    corsBuilder.AllowAnyHeader();
    corsBuilder.AllowAnyMethod();
    corsBuilder.AllowAnyOrigin();
    corsBuilder.AllowCredentials();
    services.AddCors(options =>
    {
        options.AddPolicy("AllowAll", corsBuilder.Build());
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseCors("AllowAll");
}

Of course, set your policies based on your app's needs, this just allows all for testing. Example here and official .NET Core docs here provide more details.

Community
  • 1
  • 1
Jerms
  • 103
  • 11
  • I think corsBuilder.AllowCredentials(); and AllowAnyOrigin() will not work toghether. According the documentation AllowCredentials must allow specific Origins – Claudio Ferraro Sep 11 '19 at 10:22