I have a webserver from where users can download files that are specific for each user. To be sure each user can only download its own files they must authenticate via Basic-Authentication. So for each user there is a windows-account on the server that has read permissions to the user specific folder.
Now I want to move this functionality to another server. I do not want to create windows accounts for the users but still keep the Basic-Authentication. So I use the Custom Basic Authentication HTTP Module in combination with a Custom MembershipProvider that lets me define users in the web.config.
The authentication works quite fine but after logging in with either jack
or jill
(see web.config) I'm able to access both locations Dir1
and Dir2
. This is also the case if I comment out the <allow users="jack" />
part in the location tags.
Additional Info: I created a Default.aspx file and added a
<% Response.Write(HTTPContext.Current.User.Identity.Name) %>
which returns the correct user name depending on who logged in.
<% Response.Write(HTTPContext.Current.User.Identity.IsAuthenticated) %>
returns True.
What do I have to do that only jack
is able to access (= download files from) Dir1
and only jill
is able to access (=download files from) Dir2
but not the other way round?
EDIT: I tried to add web.config files for each subdirectories instead of the location tags as mentioned by utkai - with the same result. Every user can access any directory.
Here is my Web.config file:
<configuration>
<system.webServer>
<modules>
<add name="CustomBasicAuthentication" type="LeastPrivilege.CustomBasicAuthentication.CustomBasicAuthenticationModule, LeastPrivilege.CustomBasicAuthenticationModule, Version=1.0.0.0, Culture=neutral, PublicKeyToken=F20DC168DFD54966"/>
</modules>
<security>
<authentication>
<customBasicAuthentication enabled="true" realm="TEST" providerName="AspNetWebConfigMembershipProvider" cachingEnabled="true" cachingDuration="15" requireSSL="false"/>
</authentication>
<authorization>
<deny users="?" />
</authorization>
</security>
</system.webServer>
<system.web>
<membership defaultProvider="AspNetWebConfigMembershipProvider">
<providers>
<add name="AspNetWebConfigMembershipProvider" type="LeastPrivilege.AspNetSecurity.Samples.WebConfigMembershipProvider, WebConfigMembershipProvider"/>
</providers>
</membership>
<authentication mode="Forms">
<forms>
<credentials passwordFormat="Clear">
<user name="jack" password="jack"/>
<user name="jill" password="jill"/>
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
<location path="Dir1" allowOverride="false">
<system.web>
<authorization>
<!-- <allow users="jack" /> -->
<deny users="*" />
</authorization>
</system.web>
</location>
<location path="Dir2" allowOverride="false">
<system.web>
<authorization>
<!-- <allow users="jill" /> -->
<deny users="*" />
</authorization>
</system.web>
</location>
</configuration>
You can configure the <authorization> element at the server level in the ApplicationHost. config file, or at the site or application level in the appropriate Web. config file. You can set default authorization rules for the entire server by configuring authorization rules at the server level.
The location element takes precedence over any ASP.NET configuration setting in the current Web. config file. You can set the location element programmatically by using the ASP.NET configuration API, or you can set it by using the Locations tab in the ASP.NET MMC snap-in.
Windows Authentication mode provides the developer to authenticate a user based on Windows user accounts. This is the default authentication mode provided by ASP.Net. You can easily get the Identity of the user by using User.Identity.Name. This will return the computer name along with the user name.
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.
Update #3
You can enable URLAuthorization to force IIS to protect files that aren't normally processed in IIS. The solution here depends on IIS 7.x and using Integrated pipelines.
<system.webServer>
<modules>
<add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule" />
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
<remove name="DefaultAuthentication" />
<add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" />
</modules>
</system.webServer>
Updated #2 You can switch entirely to Forms authentication only by removing the custom things you've added and do the following.
I've actually tested this and it only allows jack in to dir1 and jill in dir2. Both can access the root.
If this doesn't work, we'll need to discuss more of your setup.
web.config
<?xml version="1.0"?>
<configuration>
<system.webServer>
<modules>
<add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule" />
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
<remove name="DefaultAuthentication" />
<add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" />
</modules>
</system.webServer>
<system.web>
<authentication mode="Forms">
<forms loginUrl="Login.aspx" defaultUrl="Default.aspx">
<credentials passwordFormat="Clear">
<user name="jack" password="jack" />
<user name="jill" password="jill" />
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
<compilation debug="true"></compilation>
<customErrors mode="Off"/>
</system.web>
<location path="dir1">
<system.web>
<authorization>
<allow users="jack" />
<deny users="*, ?" />
</authorization>
</system.web>
</location>
<location path="dir2">
<system.web>
<authorization>
<allow users="jill" />
<deny users="*, ?" />
</authorization>
</system.web>
</location>
</configuration>
Login.aspx - You must add in the redirect from the Login control because otherwise Forms authentication will look for a database in the App_Code directory, which doesn't exist.
<asp:Login ID="Login1" runat="server" OnAuthenticate="Login1_Authenticate">
</asp:Login>
Login.aspx.cs
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
string username = Login1.UserName;
string password = Login1.Password;
if (FormsAuthentication.Authenticate(username, password))
{
FormsAuthentication.RedirectFromLoginPage(username, false);
}
}
Update #1
I went through the example that you linked as Custom Basic Authentication HTTP Module and then followed through to The HTTP Module which has a link at the very bottom to additional source.
This source has a membership provider example using the custom basic authentication. I feel like you're running in to troubles by mixing in the Forms membership provider that you have in your web.config.
When you start to make your own separate authentication, things don't go nicely and you usually need to add in your own everything.
This code works from that additional link on my end.
As an added possibility, if you would like to let ASP.NET handle all of the membership itself and you are using SQL to store everything, consider looking at http://weblogs.asp.net/sukumarraju/archive/2009/10/02/installing-asp-net-membership-services-database-in-sql-server-expreess.aspx to see how to use the wizard to set it up in SQL.
The built in membership will be Forms authentication and be a lot less work than using custom.
Previous Version
I've never had luck with using the <location>
tags so I just put new web.configs in the directories. I've also had troubles when I don't exclude anonymous in sub folders as well. This seems to be that the browser will default to anonymous which will get through
Here is how I do it.
Root web.config
<system.web>
<authorization>
<allow roles="AccessRole1, AccessRole2" users="domain\jack, domain\jill"/>
<deny users="*, ?" /> <!-- make sure you deny anonymous with '?' -->
</authorization>
</system.web>
Sub directory web.config. Make sure you explicitly deny all other users. If you don't deny all other users, they can still get in.
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<allow users="domain\jill" />
<deny users="*, ?"/> <!-- explicitly deny all others, including anonymous -->
</authorization>
</system.web>
</configuration>
Here is a link to a good article with details to several situations, where one would want to allow/deny access to particular page or folder:
Setting authorization rules for a particular page or folder in web.config
As a side comment, in one project we do, we use the option of individual web.config file in each folder, as stated in the link as well, and it works for us just fine.
Hopefully, it helps to solve your problem.
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