Windows Authentication In Angular 2 Application and ASP.Net Web API
I am trying to do Windows Authentication for my Angular 4 app that accesses ASP.Net Web API for all of its data needs. I have a controller in my web API named with a named AuthenticationController
method Authenticate
that returns domain \ username if authentication is successful. The code for AuthenticationController
looks like this:
namespace MyAppWebAPI.Controllers
{
[Authorize]
public class AuthenticationController : ApiController
{
[HttpGet]
public LoginModels Authenticate()
{
Debug.Write($"AuthenticationType: {User.Identity.AuthenticationType}");
Debug.Write($"IsAuthenticated: {User.Identity.IsAuthenticated}");
Debug.Write($"Name: {User.Identity.Name}");
if (User.Identity.IsAuthenticated)
{
//return Ok($"Authenticated: {User.Identity.Name}");
return new LoginModels { DomainName = User.Identity.Name, Role = "Admin" };
}
else
{
throw new Exception ("Not authenticated");
}
}
}
}
Where LoginModels
is the model as follows:
public class LoginModels
{
public string DomainName { get; set; }
public string Role { get; set; }
}
I have enabled CORS in mine WebApiConfig.cs
in the AppStart folder and the code for this is:
namespace MyAppWebAPI
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//Resolve CORS Issue
var cors = new EnableCorsAttribute("http://MyAngularApplicationIP:port", "*", "*") { SupportsCredentials = true };
config.EnableCors(cors);
}
}
}
Also, I have enabled Windows Authentication in my Web.config
:
<authentication mode="Windows"/>
<authorization>
<deny users="?" />
</authorization>
</system.web>
Now in my Angular app I have a service named AuthenticationHelperService
like this:
@Injectable()
export class AuthenticationHelperService {
constructor(
private _httpHelperService: HttpHelperService,
private _http: Http,
private _requestOptions: RequestOptions,
) { }
public authenticateUser(): Observable<any> {
console.log('Calling GetUser');
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers, withCredentials: true });
return this._http
.get('WebApiURL:port/api/Authentication/Authenticate', options)
.map(this._httpHelperService.extractData)
.catch(this._httpHelperService.handleError);
}
}
Note that I have included the parameter withCredentials: true
in the request options. Also, here it _httpHelperService.extractData
just converts my response to JSON and _httpHelperService.handleError
logs the error (if any) to the console. Now I am calling this service method from the component on page load in the method ngOnInit
like this:
export class MasterComponent implements OnInit {
constructor(
private _userLoginService : UserLoginService,
private _authenticationHelperService: AuthenticationHelperService
) { }
private userName: any;
ngOnInit() {
this._authenticationHelperService.authenticateUser().subscribe(
data => this.userName = data,
error => console.log('Authentication Error :: ' + error),
() => console.log('Current User :: ' + this.userName));
}
}
When I launch the application, the browser asks me for credentials -
See the image
After entering credentials, it takes me to the home page, but the method _authenticationHelperService.authenticateUser()
does not return a username. I am getting an error on the console like this:
XMLHttpRequest cannot load "MyWebApiURL / api / Authentication / Authenticate". Pre-flight request response does not pass access control check. There is no "Access-Control-Allow-Origin" header on the requested resource. Therefore, the original text "MyAngularAppUrl" is not allowed. The response was HTTP 401 status code.
When I just call the web API authentication method from the browser, for example http://MyWebApiIP:port/api/Authentication/Authenticate
, then I get my username successfully, but not from the Angular app.
source to share
launchSettings.json
you can find this file in your project under properties folder,
{ "iisSettings": { "windowsAuthentication": true, "anonymousAuthentication": false, "iisExpress": { "applicationUrl": "http://localhost:53072/", "sslPort": 0 } }, "profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "AdvantureWeb": { "commandName": "Project" } } }
changing window authentication
source to share