Massive amount of issues getting this to work.
Thought I'd put up the common issues and the solutions having wasted a day on this and being led down many false paths by other answers.
Setup :
- Web Api 2 Server
- Server configured for NTLM (Negotiate)
- Angular website hosted on a different machine or Port
- Website connects to API to do, well, stuff.
Issues :
- Basic setup and first time you run it you get
no access-control-allow-origin header is present
- Setting Cors on the server and you still get the issue
- You eventually realise that Angular isn't setting
WithCredentials
on its calls and fix this, nowGET
works butPUT
,POST
&DELETE
fail with something about pre-flights.
And the solutions :
Firstly your server needs to be enabled for cors and this must be the first line in your app config :
WebApp.Start(_configuration.Url, app => { app.UseCors(CorsOptions.AllowAll);
OPTIONS
calls :var listener = (HttpListener)app.Properties["System.Net.HttpListener"]; listener.AuthenticationSchemeSelectorDelegate = request => request.HttpMethod == "OPTIONS" ? AuthenticationSchemes.Anonymous : AuthenticationSchemes.Negotiate;
Set your Angular code to send calls in with
WithCredentials
. There's many different ways to do this, but we used an authentication interceptor :intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const authReq = request.clone({ withCredentials: true }); return next.handle(authReq)
If you want to do anything fancy for your Auth you can create your own middleware by extending
OwinMiddleware
and overriding theInvoke
method. This can then be registerd in the pipeline withapp.Use<MyMiddleware>(paramsToConstructor)
in youroverride
method you can access the Identity of the user with :var identity = new ClaimsIdentity(context.Authentication.User.Identity.AuthenticationType);