I've created a Web Api 2 app which will only be used on the corporate network. I've read about Windows authentication in Web API so it seems to be possible. But I need to figure out the proper implementation for this. I've included the following xml in my Web.config:
<system.web>
<authentication mode="Windows" />
</system.web>
I seem to remember some type of event hook in old school webforms app. Something like BeginRequest() where a security check could be made before rendering a page. I included the following line of code as the first line in one of my controller methods but the returned value appears to just be an empty object without any meaningful info:
var identity = HttpContext.Current.User.Identity as WindowsIdentity;
Does Web API 2 support Windows authentication? Am I missing a step? Should Windows authentication work if I submit a general request from Postman for testing? I also tried this code but got a similar empty object:
var x = RequestContext.Principal;
I vaguely recall an IIS setting like "Enable Integrated Security." Can you please specify the exact setting? And would I be able to accomplish this if I'm running the app on IIS Express?
UPDATE
I followed the steps for IIS Express mentioned in one of the answers below but the code samples that I provided in my original post still didn't get a populated user object. I also updated applicationhost.config file to turn off anonymous authentication:
<anonymousAuthentication enabled="false" userName="" />
After I made that updated I resubmitted my test request via Postman but I get the following error:
<h3>HTTP Error 401.2 - Unauthorized</h3>
<h4>You are not authorized to view this page due to invalid authentication headers.</h4>
</div>
<div class="content-container">
<fieldset>
<h4>Most likely causes:</h4>
<ul>
<li>No authentication protocol (including anonymous) is selected in IIS.</li>
<li>Only integrated authentication is enabled, and a client browser was used that does not support integrated authentication.</li>
<li>Integrated authentication is enabled and the request was sent through a proxy that changed the authentication headers before they reach the Web server.</li>
<li>The Web server is not configured for anonymous access and a required authorization header was not received.</li>
<li>The "configuration/system.webServer/authorization" configuration section may be explicitly denying the user access.</li>
</ul>
</fieldset>
</div>
<div class="content-container">
<fieldset>
<h4>Things you can try:</h4>
<ul>
<li>Verify the authentication setting for the resource and then try requesting the resource using that authentication method.</li>
<li>Verify that the client browser supports Integrated authentication.</li>
<li>Verify that the request is not going through a proxy when Integrated authentication is used.</li>
<li>Verify that the user is not explicitly denied access in the "configuration/system.webServer/authorization" configuration section.</li>
<li>Check the failed request tracing logs for additional information about this error. For more information, click
<a href="http://go.microsoft.com/fwlink/?LinkID=66439">here</a>.
</li>
</ul>
</fieldset>
</div>
Do I need to configure my Postman request with some type of special header in order for this to work?
Web API assumes that authentication happens in the host. For web-hosting, the host is IIS, which uses HTTP modules for authentication. You can configure your project to use any of the authentication modules built in to IIS or ASP.NET, or write your own HTTP module to perform custom authentication.
On the taskbar, click Start, and then click Control Panel. In Control Panel, click Programs and Features, and then click Turn Windows Features on or off. Expand Internet Information Services, then World Wide Web Services, then Security. Select Windows Authentication, and then click OK.
To access the web API method, we have to pass the user credentials in the request header. If we do not pass the user credentials in the request header, then the server returns 401 (unauthorized) status code indicating the server supports Basic Authentication.
In addition to the previous answers, we also need to Pass credentials in cross-origin requests.
Server Side (Web API):
Set the SupportsCredentials property to true
on the [EnableCors]
attribute:
[EnableCors(origins: "http://exampleclient.com", headers: "*",
methods: "*", SupportsCredentials = true)]
Client Side (UI):
Set XMLHttpRequest.withCredentials to true
.
jQuery:
$.ajax({
type: 'get',
url: 'http://www.example.com/api/auth',
xhrFields: {
withCredentials: true
}
Angular:
this.http.get('http://www.example.com/api/auth', { withCredentials: true }).subscribe((resp: any) => {
console.log(resp)
}
XMLHttpRequest:
var xhr = new XMLHttpRequest();
xhr.open('get', 'http://www.example.com/api/auth');
xhr.withCredentials = true;
If you are using IIS Express, you need to update applicationhost.config
file.
This is the file version of the IIS configuration tool where you can configure the web server itself. you can find this file in the following directory:
%userprofile%\documents\iisexpress\config\applicationhost.config
or
%userprofile%\my documents\iisexpress\config\applicationhost.config
When you find it, update it as:
<windowsAuthentication enabled="true">
<providers>
<add value="Negotiate" />
<add value="NTLM" />
</providers>
</windowsAuthentication>
For IIS:
Check this for more details
Windows authentication that uses the local domain user and that is intended for intranet sites.
Example :
I implemented a TestAuthentication
method/action with a fixed route path. For the demo I do not include Authorize attributes yet. The code checks the User
property of the ApiController
. This contains the same data as Thread.CurrentPrincipal
or HttpContext.Current.User
. Make sure Anonymous Authentication in IIS is disabled otherwise the Identity.Name
will be empty.
public class WinAuthController : ApiController
{
[HttpGet]
[Route("api/testauthentication")]
public IHttpActionResult TestAutentication()
{
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);
}
else
{
return BadRequest("Not authenticated");
}
}
}
In Web.config file :
<system.web>
<authentication mode="Windows" />
</system.web>
In IE you can check the setting with Tools > Internet Options > Advanced and look for a setting Enable Windows Integrated Authentication. When you go to the tab Security and then Intranet and Custom Level, then you will find a setting at the bottom to specify if IE should logon automatically or prompt for the username and password.
Please visit below link, it has proper steps to follow for WEP API Windows authentication :
http://www.scip.be/index.php?Page=ArticlesNET38&Lang=EN
Below are the steps to configure windows authentication in web api for both local and server (IIS).
1) For Local:
a) To create a web api project in windows authentication mode, follow below steps:
After choosing ASP.Net Web Application, select Web API template and from the right side click Change Authentication button and select Windows Authentication.
b) For an existing web api project, just add the following lines in your applicationhost.config
file.
<location path="YourProjectName">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
2) For Server (IIS)
To run windows authentication after hosting the application in IIS just add following lines in your web.config
file inside system.web
node:
<authentication mode="Windows" />
<authorization>
<allow verbs="OPTIONS" users="?" />
<deny users="?" />
</authorization>
In both the cases, just use the following lines in your code that windows authentication is working properly:
if(User.Identity.IsAuthenticated)
{
//do work
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With