My website has a folder called uploads and inside there is a folder for each client.
My question is, what's the best practice to deny the user A to see the uploads from user B?
You could do this with web.config changes. See documentation here: http://support.microsoft.com/kb/815151
Basically your web.config will look like:
<?xml version="1.0"?>
<configuration>
<location path="uploads/UserA">
<system.web>
<authorization>
<allow users="UserA"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<location path="uploads/UserB">
<system.web>
<authorization>
<allow users="UserB"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
</configuration>
Perhaps look at using an HttpHandler to intercept the request and generate a 403 (or whatever you want to do) if the user is not authorized to access the requested path.
Alternatively, you could put the logic in Global.asax in the BeginRequest method.
You could use NTFS permissions on the folders, forcing the user to authenticate. I did this for a website in 2000. Although in this case that's like using a cannon to kill a mosquito.
Assume you might have something like following data-structure:
You may write a file name to database column.
So you may add a column called "Allow-Anonymous" with True/False.
Now while accessing your content from server, check the db table,
If Allow-Anonymous is False and Visiting-User is other then owner then deny page display. Otherwise you may show the content.
DataBase mock:
Id Data Path OwnerId AllowAnonymous Status
1 Data-A ~/upload/Data-A 1 False True
Code mock:
if(AllowAnonymous == True && UserId == OwnerId && Status == True)
// Show data on page
else
// Redirect to deny page
Related
Is it possible to add location tag dynamically with c# in web config?
for example, I want to add:
<location path="a/b">
<system.web>
<authorization>
<allow users="xxx"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
The folder b is created on run time, and I want to add an access to the user which created it.
The number of the folders created is unknown.
I use forms authentication.
Like #SouthShoreAK I don't think that can be done in this way, but always there are options, one approach could be by having a base web.config that you can edit an save in each folder that you create in wich you add the authorization that you need, the code that I put below does this.
try
{
//Load the empty base configuration file
Configuration config = WebConfigurationManager.OpenWebConfiguration("~/WebEmpty.config");
//Get te authorization section
AuthorizationSection sec = config.GetSection("system.web/authorization") as AuthorizationSection;
//Create the access rules that you want to add
AuthorizationRule allowRule = new AuthorizationRule(AuthorizationRuleAction.Allow);
allowRule.Users.Add("userName");
//allowRule.Users.Add("userName2"); Here can be added as much users as needed
AuthorizationRule denyRule = new AuthorizationRule(AuthorizationRuleAction.Deny);
denyRule.Users.Add("*");
//Add the rules to the section
sec.Rules.Add(allowRule);
sec.Rules.Add(denyRule);
//Save the modified config file in the created folder
string path = MapPath("~/NewFolder/Web.config");
config.SaveAs(path);
}
catch (Exception ex)
{
//Handle the exceptions that could appear
}
Your WebEmpty.config would be like this
<?xml version="1.0"?>
<configuration>
</configuration>
And your saved file looks like this
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<authorization>
<allow users="userName" />
<deny users="*" />
</authorization>
</system.web>
</configuration>
Another thing to consider would be the read/write permission to create the config file, but I think that you already have it because of the dynamic folder creation.
Hope this help.
I have two location elements in a single web.config file, and would like to change the authorization in the code behind.
The web.config location sections are like this:
<configuration>
<location path="~">
<system.web>
<compilation debug="false" targetFramework="4.0"/>
<authorization>
<allow roles=""/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<location path="~/SubPage">
<system.web>
<compilation debug="false" targetFramework="4.0"/>
<authorization>
<allow roles=""/>
<deny users="*"/>
</authorization>
</system.web>
</location>
</configuration>
From the code behind I would like to go through the location elements, and then make the changes to that specific location element. For example, c# code behind would be:
Configuration myConfig = WebConfigurationManager.OpenWebConfiguration("~");
ConfigurationLocationCollection locations = myConfig.Locations;
foreach (ConfigurationLocation location in locations)
{
if (location.Path = "~")
{
//define & clear the authorization section of the particular location element.
//create and apply rule for allow in that authorization section.
//create and apply rule for deny in that authorization section.
//save the change
}
if (location.Path = "~/SubPage")
{
//define & clear the authorization section of the particular location element.
//create and apply rule for allow in that authorization section.
//create and apply rule for deny in that authorization section.
//save the change
}
}
I have tried several different things here, but I don't have one solution that actually works so far... I need to consoldiate any change to the web.config in the root directory (~) (any change would have to be reflected in this file, not other files in the subpage). Any recommended working solution to fill in the blanks? The purpose is to allow admin users to make changes on an admin user interface to decide which users or windows groups on the internal network will be allowed to view the two locations, so I would particularly like to change the allowed roles from the code behind.
Thanks.
After several attempts, abandoned trying to make all the changes on the same file, and instead simply opened a new configuration manager instance in each location.Path.
WebConfigurationManager.OpenWebConfiguration(location.Path), then applied the rules to each individual web.config at each location. I couldn't centralize all the authorizations in one place, but at least it was working.
I would like to know if there is a way to check if a page requies authentication based on the web.config settings. Basically if there is a node like this
<location path="account">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
then I would like to check on any page if it requires authentication or not and to return true if it is under the account directory. Is this possible?
The solution is to create an anonymous identity (principal), and pass it into the CheckUrlAccessForPrincipal method. It will determine if the page is public, or requires authentication.
See code below:
var principal = new GenericPrincipal(new GenericIdentity(String.Empty, String.Empty), new string[]{});
bool requiredAuthentication = UrlAuthorizationModule.CheckUrlAccessForPrincipal(Page.AppRelativeVirtualPath, principal, Request.HttpMethod);
Are you checking the page that the user has requested? Its unlikely as the request will never get to the page. Check the url authorization workflow.
http://www.asp.net/web-forms/tutorials/security/membership/user-based-authorization-cs
I am a little confused as to what you are asking exactly, but to use your web.config to enforce authentication on a page-for-page basis, you need something like this:
<location path="Forms/Administration/Default.aspx">
<system.web>
<authorization>
<allow roles="Administrator, User, AdditionalUser" />
</authorization>
</system.web>
</location>
If you need to be more granular than that, you need to add the logic to your middle-tier and then check on page load or url request (if MVC).
i am using windows authentication with my asp.net application
different users will have different access to parts of the website.
i would like to do something like this in the config file:
<appSettings>
<role1>
<user>agordon</user><user>jsmith</user>
</role1>
<role2><user>dtodd</user><user>kveel</user></role2>
</appSettings>
is this possible to do?
when authenticating i would then get the username like this:
string username = HttpContext.Current.User.Identity.Name.ToString();
and check if that user exists in the specific role
Use the <authorization> element:
<configuration>
<system.web>
<authorization>
<allow users="*" />
<deny users="?"/>
</authorization>
</system.web>
</configuration>
You can then modify that for particular parts of your site:
<location path="Pages/Administration">
<system.web>
<authorization>
<deny roles="*"/>
<allow roles="Admin" />
</authorization>
</system.web>
</location>
You can do this, but it's really not the best way.
The problem here is that appSettings are not controlled by the Web.Config schema, so you'll need to programatically enumerate appSettings in a horrible fashion:
if (configurationSettings.HasKey("Role1")) { ... }
else if (configurationSettings.HasKey("Role2")) { ... }
else if (configurationSettings.HasKey("Role3")) { ... }
//continue ad.nauseum; it's not fun - trust me!
I know it's not what you're asking, but If you're using normal ASP.Net webforms then it's a little it of a slog; in each page/control you need to find out the current user and then determine if that user has access and then redirect or continue.
If you use ASP.Net MVC, it's a lot cleaner as you do this with attributes.
Authorize(Roles = "Managers")]
public ActionResult CompanySecrets()
{
return View();
}
What the code there is doing, is saying If the user doesn't have the Managers role, don't give them access.
To provide an opposite example, here's a similar method using Web form (msdn example):
http://support.microsoft.com/kb/311495
This is part of my web.config
<location path="Secure">
<system.web>
<authorization>
<allow users="SecureUsers" />
</authorization>
</system.web>
</location>
I want to be able to search for path of Secure and find out the user role that is specified.
My input is the path, such as "Secure" and the value I'm trying to retrieve is "SecureUsers".
I think you want to open the config and cast it as a Configuration object before you can really get what you want. You might also be able to read the config file using LINQ to XML too, but here is how you would do it otherwise.
Configuration config = ConfigurationManager.OpenExeConfiguration(Server.MapPath("~/web.config"));
ConfigurationLocationCollection myLocationCollection = config.Locations;
foreach (ConfigurationLocation myLocation in myLocationCollection)
{
if (myLocation.Path == "Secure")
{
}
}