Allow location path with querystring in web.config - asp.net

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 ;)

Related

IIS 7.5 and making anonymous authentication/forms authentication play nicely together

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.

Enforcing web.config authorization entries

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");

How to test asp.net location folder authorization programmatically

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.

ASP.NET Forms Authentication via Querystring

I currently have an ASP.NET 3.5 SP1 running on IIS 7. I have enabled forms authentication using .NET Membership and setup some folders that are restricted according to roles I have created. For instance, if an anonymous visitor tries to access the file http://www.example.com/restricted/foo.txt, he/she will be redirected to a login page, as expected. So far so good.
What I would like to do is provide access to protected files by allowing visitors to specify their login credentials in a query string, something alone the lines of:
http://www.example.com/foo.txt?user=username&pass=pwd
Is this possible at all?
you should be able to write an http module that intercepts the request and authenticates the user based on the querystring. However, just for the sake of completeness, I'd like to question whether it's a good idea to provide users their username and (in particular) password in plaintext.
You could easily create a download page that would authenticate the user and then forward them to the requested file. Something like navigating to Download.aspx?user=username&pass=pwd&file=foo.txt.
This however is NOT recommended. You should never require users to pass login information via a URL.
A secondary answer based on comments you've made to other questions is that you could simply put your download page in a directory. The subfolder could have a web.config that allows unauthenticated users access to the contents within :-)
something like:
<configuration>
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</configuration>

How do you make the user stay on a particular page of a website?

So here is what i am trying to achieve
When a user logs in and his password has expired, i redirect him a change password screen.
I would like the user to change his password prior to going to other links in a menu
I want to redirect back to this changepassword.aspx when ever he attempts to leave, unless he changes his password
So how do I do this? and more importantly where?
Thanks for the help!
EDIT: I know we can use response.redirect, but it cant be used in the Unload operation
EDIT: ok i am not asking this right, i need help in keeping the user on the page - how do i do that and which part of the page [load, unload, etc]
Please don't do that. That kind of PITA UI is very irritating. Just expire their password and then fail their access if they don't change it.
Don't treat your users like children (unless they really are children and maybe not even then)
Edit: Made this a Community answer, as I'm just preaching not answering ;-)
Explained: Forms Authentication in ASP.NET 2.0
"This module explains how forms authentication works in ASP.NET version 2.0. It explains how IIS and ASP.NET authentication work together, and it explains the role and operation of the FormsAuthenticationModule class."
In the web.config, I have the authorization section saying
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
<location path="ChangePassword.aspx">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
Set a session var if they need to change their password
On every pageload check for that session and if it exists (and they're not on the password change screen), redirect.
We used to use a masterpage on our site and in the Page_Load event of that, we redirect the user to our changepassword.aspx page.
We also used (or abused, depending on your viewpoint) the Profile element of asp.net membership and simply set a MustChangePassword entry to true in it. It means that when they log-in, you can see if the MustChangePassword entry is set in their profile and redirect to the change password page. It certainly keeps them on the page.
People are right to suggest that sticking it in every page load is silly but the overhead is tiny to check one element in the users profile and you at least can force currently logged in users to change their password.
Set a flag in the user's session indicating that they need to change their password, then check that flag from all your other pages and redirect them to the change-password page if necessary.
I'd set a variable in his session, then in your Global.asax Application_BeginRequest event check for the Session variable and redirect if needed.

Resources