tl;dr: Why does
<allow users="?">
work on IIS Express, but not on IIS?
Background
I have a new asp.net web-forms project. When running locally on Windows 7 IIS Express, i can block "all users" from accessing the site by adding a deny * rule to web.config:
web.config
<configuration>
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</configuration>
this causes me to be denied access:
And so that makes sense.
I can deny access to anonymous users
I the web.config, i can block access to anonymous users, by using the ? marker, rather than the all (*) marker:
<authorization>
<deny users="?" />
</authorization>
And because i am not authenticated, i will again be 401 Unauthorized:
And that makes sense.
Allow anonymous
I can allow anonymous access, by changing the deny in web.config to allow:
<authorization>
<allow users="?" />
</authorization>
And now I am brought right to the homepage:
and that makes sense.
But doesn't work on IIS
The above works on IIS Express. But when i publish to Windows Server 2012 R2 IIS 7.5, trying to allow anonymous (?) users does not work:
That makes no sense:
works on IIS Express
fails on IIS 7.5
Try allowing everyone
Rather than:
allowing just anonymous users (?)
i can try to allow all users (*)
i change web.config again to allow everyone (*):
<authorization>
<allow users="*" />
</authorization>
And locally i can still access the site:
but once i publish to IIS 7.5 it still fails:
What's going on?
I'm not doing anything wrong. So what do i need to change?
Initially i created an empty web-site, and started adding things to it. Later, i need to create real web-site (with pages that displayed information, and buttons to click), so i started over with an Empty Web Forms web-site.
My feeling is that Owin broke everything.
Nevertheless, what is going on?
Solution
I found it. There are some settings about a web-site that do not go with the web-site. That is, there are configuration options about a web-site that you cannot configure through web.config, or any other file in the web-site's folder. In particular:
I don't know where IIS stores the use of anonymous authentication. But without anonymous authentication, IIS is unable to realize that an anonymous user is anonymous.
Enabling anonymous authentication:
causes IIS to realize that anonymous users are anonymous.
That explains:
why it worked on IIS Expres
why it didn't work on IIS 7.5
why it still didn't work when both web-sites have the exact same set of configuration files
It doesn't explain why IIS doesn't treat anonymous users as anonymous when anonymous authentication is not enabled; but that's another issue for another day. If you've read down to here, you can copy-paste everything i just said, and get the accept. Otherwise i'll have to wait two days to answer it myself. Better you get the rep.
You learn something by finding the solution. Congratulation.
Authorization happens after authentication. So on IIS you saw the 401.2 error page before the authorization rule was ever processed. Only after a proper authentication method is set to enabled, then things start to work out.
IIS Express should give you the same 401.2 error page if you disable all its authentication methods. Just a note.
A Microsoft Patterns and Practices article explains more about why you need anonymous authentication enabled in order to allow anonymous users:
ASP.NET authentication is a two-step process. First,
Internet Information Services (IIS) authenticates the user and creates a Windows token to represent the user.
If IIS is configured to use anonymous authentication, a token for the IUSR_MACHINE account is generated and used to represent the anonymous user.
IIS-then passes the token to ASP.NET.
Note Because forms authentication does not rely on IIS authentication, you should configure anonymous access for your application in IIS if you intend to use forms authentication in your ASP.NET application
In IIS, anonymous access is enabled for all applications that use forms authentication.
IIS allows the request because anonymous access is enabled in the IIS metabase. ASP.NET confirms that the authorization element includes a tag.
There are two ways for a user to be authenticated when issuing a request to IIS:
IIS authenticates your identity itself (using Basic, Digest, or Windows authentication)
IIS is configured to allow "anonymous" authentication, and the web-site will handle authentication itself
The confusing part here is that there is a difference between:
anonymous as far as IIS is concerned
anonymous as far is ASP.net Forms authentication is concerned
From IIS's point of view any request that will be authenticated using Forms (or Owin, or any other custom authentication module) is still an anonymous request:
| IIS Authentication | Application Authentication |
|--------------------|----------------------------|
| Basic | |
| Digest | |
| Windows | |
| Anonymous | Forms |
| Anonymous | Owin |
| Anonymous | BasicAuthModule |
When i was attempting to allow anonymous users access:
<allow users="?" />
That is a Forms authentication directive. But in order to even reach forms authentication, you must allow anonymous authentication at the IIS level.
Related
I’m currently developing a web site that uses windows authentication, with ApplicationPoolIdentity configured with Identity=Application Pool. I can connect by login with my administrator user when asked by the browser and it works perfect, but if any other user tries to access, the browser asks for the credentials 3 times and then it throws a 401 Error.
Test scenarios:
If the server is configured with Anonymous Authentication ON, everybody is able to open the page.
If I try to set the application pool Identity to a regular user account, IIS doesn’t recognize the user/password provided.
The folder C:\inetpub\ was set with full control to Everyone, but the users can’t connect anyway.
The folder C:\inetpub\ was set with full control to a specific user, but the user can’t connect anyway.
Following a recommendation from another post, the following section was added to the web.config :
<authorization>
<allow users="*"/>
</authorization>
The windows logs in the Event Viewer don’t store anything about a failed login.
thanks for your comments
Update
i enabled and add Failed Request Tracing Rules to web site
it was result
ModuleName :IIS Web Core
Notification : AUTHENTICATE_REQUEST
HttpStatus : 401
HttpReason : Unauthorized
ErrorCode : Access is denied (0x80070005)
i searched this error but the post tell me, maybe permissions, but i set everyone as full control and it doesn't working
I have build a MVC 5 application. Now is time to publish it to production.
The infrastructure consist of two servers: one that can be accessed on internet and the other that is accessed only in intranet.
Server is Windows Server 2012 R2 and uses IIS 8.5 to host the application.
The application consist of backend and frontend. Backend's functionality are accessible only with login.
The problem that I want to solve is: How can I prevent login to the application from Internet and allow it only in intranet?
I think that might be some configuration on web.config to prevent opening of login page.
I have read a lot articles, but all the results are to prevent pages of unauthorized users. In my case login controller has [AllowAnonymous] attribute and it can be accessed without authorization.
If it can be done with a simple configuration in web.config I am going to add a key in web.config to keep track where it is the server on internet or the server on intranet like:
//for server accessible on intranet
<add key="serverType" value="PUBLIC"/>
// or
//for server accessible on intranet
<add key="serverType" value="Private"/>
And in the corresponding controller for login I will check for the value and if it is ConfigurationManager.AppSettings["serverType"] == "PUBLIC" I will redirect it to site public home page.
Does this solution have any security issue?
In this case, I would change the config with transforms or Parameterization (I prefer this one) to use the appropriate authentication type. For example, Anonymous for public and Windows/Forms Auth for private. You would have a transform/parameterization for each server type.
The following posts provide more specifics around ASP.NET security.
https://msdn.microsoft.com/en-us/library/3yfs7yc7.aspx
https://msdn.microsoft.com/en-us/library/7t6b43z4.aspx
http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx
I've seen plenty of information on the web about how to allow anonymous access to a specific SharePoint Application page by inheriting from UnsecuredLayoutsPageBase, etc.
How can I achieve the same thing for an ashx handler that lives in the layouts directory? By default, SP will require authentication to get to the handler. I can get around this by allowing anonymous access to the site itself, but I can't get away with that...I need anonymous access to only the handler. I have tried to stick a web.config file in the same directory as the handler and allow anonymous access there, but that still doesn't work.
I had the same situation. You stated that you "can't get away with [...] allowing anonymous access to the site itself", so I'm not sure if my solution will work for you, but here it is:
Turn on Anonymous Access to SharePoint (Steps 1 - 6 of http://www.topsharepoint.com/enable-anonymous-access-in-sharepoint-2010)
In IIS manager, turn on Anonymous Authentication to the layouts subfolder that contains your ashx file. (SharePoint appears to still require authentication to application pages because they extend from LayoutsPageBase).
Alternatively, on my dev site I enabled SharePoint Anonymous Access, turned on anonymous access from IIS manager, and then created 2 web.config rules
<system.web>
<authorization>
<deny users="?" />
</authorization>
...
</system.web>
<location path="_layouts/Folder/Anonymous.ashx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
However, I think that version is overcomplicated. I prefer the first option.
I need to secure a legacy help site on our network that points out to the world. Ideally, I want to have people authenticate with their active directory logins, because everybody in the company is already there, and they already know that stuff. Ideally, I'd need to set the default domain so people don't have to type that.
I have an example to model my solution after, but to call it weird is a bit of an understatement. Anonymous access is enabled, with authenticated access restricted to Integrated Windows Authentication and Basic Authentication, with no initial domain or realm set. The web.config file in the website has only this in its authentication field:
<authentication mode="Windows" />
<authorization>
<deny users="?" /> <!-- Allow all users -->
</authorization>
Of course, the site I am securing is pure HTML, so I am not even sure a web.config file will work. Is there a graceful, sustainable way to go about this? Unfortunately, I am unable to find much of anything on Google.
Turn of anonymous authentication in IIS and enable Integrated Windows Authentication. That will work outside asp.net. If it's pure html, the web.config isn't being used.
I have a server set up with IIS, and my site has some pages which should allow anonymous access and some pages which should require the "Integrated Windows authentication". On the Authentication Method screen in IIS it looks like you can enable both "Integrated Windows Authentication" and anonymous access, but the documentation I've read seems to indicate you can only use one or the other.
Does anyone know how to allow anonymous access to some pages and require NTLM authentication on others?
Thanks,
Enabling both Anonymous Access and Windows Authentication means it will try Anonymous Access first, if that fails it will fall back to Windows Authentication.
If you need to do both, you can either do as suggested with the web.config, or put the pages that need protection in a sub-folder in IIS, and enable only windows authentication on that.
You have to use the authorization section in web.config.
To make only specific folders require authentication, you can have web.config with only the authorization element in subfolders like so:
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>