Ultimate goal is to provide protection against programming mistakes. I want to make sure that every page in a portion of my web application has a role specified like below. Ideally I would like to programatically check all requests coming in ( think IHttpModule ) and make sure that the page being requested has a role specified.
I can't seem to find how to get programatic access to the allowed roles.
<location path="foo.aspx">
<system.web>
<authorization>
<allow roles="modifier"/>
</authorization>
</system.web>
</location>
make a deny * in the root, so every page is not allowed, until it is explicitly activated....
Stumbled across this AuthorizationRuleCollection.
From MSDN, I've not tried it as I solved my problem using a tecnique similar to the AuthorizeAttribute in the MVC framework.
System.Configuration.Configuration configuration = WebConfigurationManager.OpenWebConfiguration("/aspnetTest");
AuthorizationSection authorizationSection = (AuthorizationSection)configuration.GetSection("system.web/authorization");
Related
I've got an ASP.NET MVC 4 application that I run under the site level of an IIS web site.
So the dir structure looks like this:
\IIS
\Site
\bin
\Content
\Views
The MVC 4 app uses Forms Authentication via Username and Password, but I have a requirement to lock down the full site and turn off anonymous authentication at the IIS level.
The goal of this requirement is to allow users only to land on a home page and logon page. The problem is if I turn off anonymous authentication then users can't even get to home or login.
Another thing we want to prevent a user from being able to go to /Content/Scripts/MyScript.js in their browser.
I'm using bundling so those file are there and don't get used by me besides when I bundle things up.
Is this even possible since IIS and MVC 4 auth are at completely different level? If it is possible what options do I have?
Chris Pratts answer is correct. You can successfully turn of anonymous authentication and let MVC4 handle all of that for you.
Make sure in your web.config you have the following
<modules runAllManagedModulesForAllRequests="true"></modules>
In your system.webserver section.
Another thing you can do is make use of the locations tags in IIS to prevent user access to different parts of the site.
For example, you could put this in your web.config
<location>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
This ensures that only authenticated users can access the site. You can then further refine this.
<location path="External">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Basically, now any request to /External will be allowed for all users (regardless of authentication). You will probably want to put all your scripts in here that you need unauthenticated users to access.
If there was a specific directory you didn't want anyone to access, you could do something like
<location path="/Content/Scripts">
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</location>
Now any access to that location will be prevented by default in IIS. Give that a try, it should satisfy your requirement to have the scripts available for bundling, but not accessible if someone browses directly to it.
I only halfway got what I wanted, but here is what I ended up doing. I have anonymous authentication enabled at the site level and used Forms authentication for specific controllers. This was how I originally had it so nothing changed here.
Since I am using bundles the users never really need to look at the .js so I used Request Filtering by file extension so block any .js and even .css I don't want exposed.
This works because the bundling doesn't make http requests to those files and the bundles themselves don't have the normal JavaScript and CSS file extensions.
You don't handle this at the IIS-level. You simply allow Anonymous Auth and then add [Authorize] to every controller. Then only on your home and login actions add the attribute [AllowAnonymous].
As to the second part of your question, you can't really stop this. MVC bundles on the fly, so it needs the actual files to be there. If they're never referenced, though, they're black holes: the user would have no way of knowing what file to request, so it's kind of security by obscurity.
I have this in my web.config
<location path="ChangePassword.aspx">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web> </location>
The problem is that, while accessing the page works, i need to allow acces to this page with querystrings as well, which does not work:
ChangePassword.aspx?mode=
ChangePassword.aspx?userid=xx&mode=
How can I do that? The parameters will have dynamic values all the time of course, I cant hardcode IDs in web.config.
EDIT for better understanding of the problem
The purpose= non-logged user must have access to the ChangePassword.aspx page with any querystrings it receives.
The problem for non-logged users:
They can access ChangePassword.aspx
They can NOT access ChangePassword.aspx?parameter=value
If a user can access the page, they can add a query string to the path.
The authorization mechanism operates on the file location only - you can't make it operate on the query string parameters.
If you want to change the page behaviour according to the parameters you should do that in your page code.
You can easily access the query string parameters on the page:
Request.QueryString["UserId"]
The problem is not in the web.config: your settings regarding the tag are correct.
The problem is the link
ChangePassword.aspx?Userid=xx&mode=
The character that does not allow a correct routing to your page is the "&".
Make sure it is written using proper Xml encoding (which, amont other things, will replace all '&' characters with '&').
This should work well:
ChangePassword.aspx?Userid=xx&mode=
Or you can use
System.Web.HttpUtility.HtmlEncode(yourUrl);
I hope it is useful ;)
I have an location element in my web.config like so:
<location path="Admin">
<system.web>
<authorization>
<allow roles="Domain\Development"/>
<deny users="*" />
</authorization>
</system.web>
</location>
This works to only allow members of the development group access to this folder.
I was wondering if there is a way to simply test if a user has access to this folder?
One scenario is creating menu items. I'd simply like to hide or not render links to pages in this folder if the user does not have the proper rights.
Is there a way to do this in code. I don't want to have to hard code a check for membership in Domain\Development rather I'd like to use asp.net to tell me if this current user has access.
This would be nice if the rules get more complicated etc. Also having this in one place enforces DRY (Don't Repeat Yourself).
Through a related question I found the answer. Call UrlAuthorizationModule.CheckUrlAccessForPrincipal. (Documentation is here.) You can give it a path and a user (such as Page.User for the current user), and it will tell you if the user can access that path.
I like this for exactly the reason you mentioned: You can put your access logic in one place.
We're currently in the process of re-creating a brand new security model that dwarfs our existing process. Right now, we plan on grabbing a user's roles during the login process and then using a Base Page class to check if the user has the role of the corresponding page the user is navigating to.
We can limit the menu's options by the user's roles as well, but we have had problems with users navigating to pages in our system by typing them in or having old bookmarks. Obviously, we need some sort of page level access.
A simple function in our Base Page class that checks the role in the Arraylist against the page's assigned role would work, but I was wondering if there was any built-in functionality to support this or a cleaner solution possibly.
Have you looked at ASP.Net Membership for this yet? It takes care of all of the scenarios you listed above (trimming menus, page security,) and in a very easy to use manner.
See here for more information about membership - http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx.
Are you using built-in membership?
If so, you can use the location section of your web.config file to restrict access to individual pages or entire directories. From MSDN:
The following example allows an
anonymous user to access the
Logon.aspx page:
<configuration>
<location path="Logon.aspx">
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</location>
</configuration>
When using a gridview and not logged into a asp.net website, the java scrpit does not appear to work.
If I am logged in as a user, any pages with gridviews work fine.
The only error I'm getting when checking the javascript with Firebug is
'ReferenceError: DES_ValOnSubmit is not defined.'
This is a reference to a Peter Blum javascript function, but have no idea why it would fail for anonymous users, and it does for logged in users.
Thanks for any help.
I'm not sure what your authentication scheme might be, but if you are using the authorization tags in the web.config file, you might need to make an explicit exception for your javascript if you are denying the anonymous user to sections of your web site. Something like this:
<location path="MyScriptFolder/MyPeterBlumJS.js">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
You can also just set the path to "MyScriptFolder" to allow all users access to your javascript as needed.