Disable Windows Authentication for WebAPI - c#

I am playing with an MVC4 application and using WebAPI for fetching/sending all my data. In a controller I am using an HttpClient request to get the data and all is working fine. The issue I am facing is that when Windows authentication is enabled in the project, the web API calls are returning a 401 Unauthorized error.
the code in my controller that does the calling is:
using (var client = new HttpClient())
{
var invoiceDetailUrl = BASE_URL + Url.HttpRouteUrl(
"DefaultApi",
new { controller = "InvoiceDetails", id = id }
);
var result = client.GetAsync(invoiceDetailUrl).Result;
}
Windows authentication has to be on for the site, but not necessarily the Web API controllers. I have tried excluding the API controllers in the web.config like below:
<location path="api">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
but the additions to the web.config did nothing.
Any suggestions?

Authentication
Web API assumes that authentication happens in the host. IIS uses HTTP modules for authentication. asp.net now allow you to configure via web.config any of the authentication modules built in to IIS or ASP.NET, or write your own HTTP module to perform custom authentication.
You can use multiple authentications at the same time, it's not a problem.
In you case, you need both Windows authentication & Anonymous authentication.
Windows authentication will secure your WebSite, and Anonymous authentication will open your Web Api.
Configure Authentication in IIS
Hosting on IIS Express
Open the Properties pane (via F4 and not the properties of the project), and apply desired authentication
Set "Anonymous Authentication" to "Disabled".
Set "Windows Authentication" to "Enabled".
Hosting on IIS 7 or later
In IIS Manager, open the Authentication feature in the features View. Enable/Disable desired authentication. If an authentication system is not an option (such as Windows), you'll need to install it via the Server Manager (Add Role Services).
Authorization
asp.net Authorization
In ASP.NET, there are two ways to authorize access to a given resource: File and Url authorization. I won't explain it here but you can read this article.
The important thing is that you can allow/deny users and/or groups in web.config.
The default config in Windows authentication is to allow only authentication users *****, like this :
<authorization>
<deny users="?" ></deny>
</authorization>
If you want to allow anonymous users ? under the url location "api", add this :
<location path="api">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
Web Api Authorization
asp.net Web Api Authorization happens later in the pipeline, closer to the controller. That lets you make more granular choices when you grant access to resources.
Web API provides a built-in authorization filter, AuthorizeAttribute. There is also an AllowAnonymousAttribute.
You can use it Globally, on a Controller or on an action.
By default, all actions are authorized.
Testing Api
Via Browser
Integrated Windows authentication works with any browser that supports the Negotiate authentication scheme. It's the cas for Internet Explorer and now Chrome : they will automatically provide Windows Credentials when browsing a Web Site with Windows authentication. Firefox does not support this scheme, so I often test authentication with this browser.
Via HttpClient
Your HttpClient needs to provide Credentials when invoking the Web Api (like browsers). This is done by configuring an HttpClientHandler whith appropriate credentials.
//use default credentials aka Windows Credentials
HttpClientHandler handler = new HttpClientHandler()
{
UseDefaultCredentials = true
};
//use username/password credentials
HttpClient client = new HttpClient(handler);
var handler = new HttpClientHandler {
Credentials = new NetworkCredential(username, password)
};
var httpClient = new HttpClient(handler);
Hope this will help you.
One last important thing in you case, is that your Web Api does not allow anonymous users at all ! Because you are using Default Credentials in your HttpClientHandler, this means that your service requires Windows authentication. You don't have to configure any credentials in an open & public service.

I came across this question while trying to do something very similar and wanted to add to the answer given above. I haven't found a lot of detailed information out there on how to do this. Just bits and piece all over the web. So hopefully this will add to what's out there.
I have an MVC4 application that has a WebAPI part to it. The MVC app needs to use Windows Auth, but the WebAPI portion needed to be anonymous and have Windows Auth turned off. While the above solution worked for ncbl, it didn't work for me because in my scenario I was not using code to handle credentials. In my scenario, I wanted a web.config or IIS based solution. I started with Cybermaxs' web.config solution and added to it. Here's what I ended up with.
<!-- Configure the virtual path api -->
<!-- This section is like a mini-web.config for the virtual path -->
<location path="api">
<system.web>
<authorization>
<!-- All anonymous users access to the virtual path api -->
<allow users="?" />
</authorization>
</system.web>
<!-- Need to include the security overrides else it will inherit from the root of the application -->
<system.webServer>
<security>
<authentication>
<!-- Need to enable anonymous access and turn off Windows authentication for the virtual path -->
<anonymousAuthentication enabled="true"/>
<windowsAuthentication enabled="false"/>
</authentication>
</security>
</system.webServer>
</location>
The key for me was to add the <system.webServer> section to the web.config so that I could override the authentication for this virtual path. I tried to do this in IIS, but since it was a virtual path, i.e. /api doesn't exist on the web server, this was not possible for me.
Note: Be aware, IIS might have a config file at a higher configuration level that is locking the <authentication> section, such as in the application.config or machine.config. An element might have the the attribute allowOverride set to false. I was getting a HTTP Error 500.19 (HRESULT: 0x80070021) at first and had to go into the application.config file to change this attribute. I found more details on this error here.
Once I had this additional section in the <location> section of my web.config I made sure to decorate my api controller with [AllowAnonymous]. Then bam...it all started to work.
This is how I have authentication and authorization setup for the root of my application.
<system.web>
<authentication mode="Windows" />
<authorization>
<!-- Deny all anonymous users at the root of the application -->
<deny users="?" />
</authorization>
</system.web>

This is what I needed to do:
<location path="api">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>

Related

Authentication issue when using ADAL to retrieve Visual Studio Online work items on ASP.NET

I'm writing an ASP.NET web application that will have read/write access to our organization's VSO work items. In order to be able to track who made which changes, I'm looking to authenticate the currently logged in user using Windows Authentication. OAuth is unfortunately not an option, since it's been disabled in our org's VSO.
I currently have the following basic code in my controller:
var client = new TfsTeamProjectCollection(new Uri("https://orgName.visualstudio.com/"));
WorkItemStore workItemStore = client.GetService<WorkItemStore>();
projectsList = workItemStore.Query(#"some query");
This is working perfectly fine when I run locally. Upon deploying to the server, it fails with a 401 Unauthorized error. I have both Windows Authentication and ASP.NET Impersonation enabled. Impersonation seems to be working, since
System.Web.HttpContext.Current.User.Identity.Name;
System.Web.HttpContext.Current.Request.LogonUserIdentity.Name;
WindowsIdentity.GetCurrent().Name;
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
all return my DOMAIN\username (when disabling ASP.NET Impersonation, the last two return NT AUTHORITY\SYSTEM as expected).
What I find weird is that when I actually provide TfsTeamProjectCollection with Basic authentication parameters like this
var client = new TfsTeamProjectCollection(new Uri("https://orgName.visualstudio.com/"), new NetworkCredential("DOMAIN\username", "password"));
it still fails (works in localhost, fails when deployed).
I've looked for quite a few solutions, but nothing seems to be working for me here. For reference, my Web.config has the following lines:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
<authentication mode="Windows" />
<identity impersonate="true"/>
<authorization>
<deny users="?" />
</authorization>
</system.web>
VSTS does not support Windows Authentication. So you need to add code in your application to handle the authentication.
VSTS support the three authentication type below:
Basic Authentication: You need to enable Alternate authentication credential or use Personal Access Token and then use NetworkCredential(basicAuthUsername, password).
Authentication with Microsoft Account, use VssClientCredentials() or TfsClientCredentials().
Authentication with Azure Active Directory, use AadCredential().
For detailed information, check this link: Authenticating (Visual Studio Team Services).

Webapplication fails to load content when authenticated using windows authentication

I'm developing a ASP.NET MVC webapplication currently running on IIS Express (for development).
The webapplication has two pages
Computer
Department
General authentication settings in web.config
<system.web>
<authentication mode="Windows" />
<authorization>
<allow users="*" />
</authorization>
</roleManager>
</system.web>
The DeparmentController enforces authentication using the authorize attribute:
[Authorize(Roles = #"DOMAIN\Administrators")]
When visiting the computer page unauthorized, all content loads fine.
When visiting the department page, I'm prompted to enter my credentials. The authentication works as expected, but I get '500 Internal Server Error' on css, js and ico files.
During my research, I only found the exact same problem the other way around. Where the static files where not loaded for unauthorized users.
Did you implement windows authorization within iis as well, also does your user have permission to the directories that the page is displaying?

windows authentication in asp.net

In Asp.net Application for windows authentication
In aspx page
asp:Label runat="server" ID="windows"
aspx.cs page
windows.Text = User.Identity.Name;
webconfig:
authentication mode="Windows"
but authentication is not performed what problem ??
Add the following in your web.config under system.web to make sure that the windows authorization is triggered:
<authorization>
<allow users="?" />
</authorization>
Your web.config wants to contain like this:
<configuration>
<system.web>
<authentication mode="Windows" />
<anonymousIdentification enabled="false" />
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
This will force all users to use their windows/Active Directory login. A 401 Access Denied error will be given to those who don't log in.
Because Integrated Windows Authentication uses the current Windows
user information on the client computer for the authentication, it
does not immediately prompt the user for a user name and password.
However, if the authentication exchange cannot identify the user, a
dialog box appears that prompts the user for a Windows user account
user name and password
Source: How to implement Windows authentication and authorization in ASP.NET
Try adding the following block to see if it's working
<authorization>
<deny users="*" />
</authorization>
After adding this, run the application and you should get HTTP 401 - Access is denied error.
You can customize authorization from then on.
UPDATE:
Here's a different approach and how to configure it via IIS management console:
Deploy your site to IIS
Click on your site and select Authentication
Disable Anonymous Authentication and enable Windows Authentication as shown in the image below
Go back to features and select .NET Authorization Rules. Here you can add allow/deny rules on a role or user basis.
To test your current code deny anonymous users and allow all. When you connect to your application you should be able to use the Windows user you used to log in.

Can't login to website using windows authentication IIS

I've been searching for a solution for this headache for a quite long.
I have a website that I want to deploy to my web server, so I'm using IIS 7 and followed these steps to authenticate logging into it:
1- Open IIS
2- Add Website (with random port number)
3- Set the application pool for it to a specific Identity
4- Disable Anonymous authentication then enable Windows Authentication.
5- Remove "Allow All users" rule
6- Add allow rule for an admin user and give him full control access
When I try to access it it asks for a username and password which must be the same user as the one added in step 6 .
The problem is whenever I click ok the logging window keeps popping up and can't access the website as a result
I also tried to add deny rule for anonymous users
Is there anything must be added to web.config file or something ? Do I need to install something or disable something ?
Any suggestion is very appreciated
EDIT
This is my web.config file authorization section
<system.web>
<authentication mode="Windows" />
<compilation targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<pages validateRequest="false"></pages>
<identity impersonate="false" />
<authorization>
<allow users="SomeUser" />
<deny users="*"/>
</authorization>
</system.web>
After spending hours trying to solve this finally I figured out the solution
1- Open IIS
2- Add Website (with random port number)
3- Set the application pool for it to a specific Identity
4- Disable Anonymous authentication then enable Windows Authentication.
5- Remove "Allow All users" rule
6- Add allow rule for an admin user and give him full control access
Note: all previous steps were made using IIS wizard
7- After openinig web.config file I can't find any changes after adding allow rules so, I had to do it manually by adding <authorization> tag then adding these rules in the same order (this order is very important either it won't work)
<authorization>
<allow users="<the user that you want to give an access>" />
<deny users="*" /> <!--to deny all other users-->
</authorization>
From MSDN, you need to enable windows authentication both in IIS and ASP.NET application:
Start Internet Information Services (IIS).
Right-click your application's virtual directory, and then click Properties.
Click the Directory Security tab. Under Anonymous access and authentication
control, click Edit.
Make sure the Anonymous access check box is not selected and that Integrated Windows authentication is the only selected check box.
In your application's Web.config file or in the
machine-level Web.config file, ensure that the authentication mode is
set to Windows as shown here.
...
<system.web>
...
<authentication mode="Windows"/>
...
</system.web>
Enabling windows authentication on IIS so that IIS authenticates the user.
Adding a setting to your web.config so that ASP.NET knows what authentication provider to use. In this case, ASP.NET uses windows authentication provider to set the value of the current User property to a WindowsIdentity based on the credentials supplied by IIS.
Also check for authorization:
The rules are checked from top to bottom and stopped at first matching rule. Therefore, you should specify allow before deny. Example:
<authorization>
<allow users="John"/>
<deny users="*"/>
</authorization>

Authorization in mixed web forms & mvc4 app

I have a project that has been using ASP.NET Web Forms for a long time now, and the security scheme had us denying all users in the root web.config, and allowing users in specific areas of the site based on web.config's in certain folders like so:
<!-- Root Web.config -->
<authorization>
<deny users="*" />
</authorization>
<!-- ~/Admin Web.config -->
<authorization>
<allow roles="AdminRole" />
<deny users="*"/>
</authorization>
I'm adding MVC4 to this project, and my original understanding was that Authorization was controlled through attributes like so:
[Authorize(Roles="OtherSectionRole")]
public class OtherSectionController : Controller
{ ... }
This doesn't seem to work, even when I use Roles="*". Only when I remove the root web.config deny * can I hit the controller actions. Am I missing something? I'd rather not remove the catch-all authorization at the root level to get the MVC stuff working. Thanks in advance!
We had to do something similar a while back, and we wound up turning it on its head. What I mean by that is we made the legacy asp.net site a sub app of the mvc app rather than the other way around. In the mvc app, we set the configuration of the login page (we were using membership with these sites) to the page in the legacy site, and then we left the legacy site's web.config as is.

Categories

Resources