Reputation: 1887
Well I am having following code written in master page: -
<authentication mode="Forms">
<forms loginUrl="Loginpage.aspx" />
</authentication>
Now it will redirect to "Loginpage.aspx" if authentication fails.
Now what If I would like to override this authentication for few pages. Also note that the number of pages and page names are not available at design time, so cannot include the aspx page names in configuration file.
Is there anyway to override authentication for few aspx pages?
-Anil
Upvotes: 0
Views: 7479
Reputation: 35925
You should usually have one point where users can be authenticated - get confirmed that they are who they claim they are. Next, you are probably talking about authorisation, which is a matter of allowing/denying performing certain operation to the user, like sending a GET request. Authorisation rules in a simple scenarios can be configured in the web.config through location element, as presented by Tom.
Upvotes: 0
Reputation: 9945
You can listen to the AuthorizeRequest event and act accordingly. Create your own Http Module to do this.
Three options:
use the configuration settings above together with generating folders with web.config entries. This is a pretty shoddy way of doing it.
listen to the event AuthenticateRequest, the code looks something like this:
public class UserAuthenticationModule : IHttpModule
{
private HttpApplication _Context;
private RoleManagerModule _RoleManager;
public void Init(HttpApplication context)
{
_Context = context;
context.AuthenticateRequest += AuthenticateUser;
_RoleManager = (RoleManagerModule)context.Modules["RoleManager"];
_RoleManager.GetRoles += roleManager_GetRoles;
}
// http://stackoverflow.com/questions/1727960/how-to-keep-roleprovider-from-overriding-custom-roles
private void roleManager_GetRoles(object sender, RoleManagerEventArgs e)
{
if (_Context.User is UserPrincipal)
e.RolesPopulated = true; // allows roles set in AuthenticateUser to stick.
}
private static void AuthenticateUser(object sender, EventArgs e)
{
var app = (HttpApplication) sender;
if (app.Context == null) return;
var user = app.Context.User;
// not signed in, forms authentication module takes care of redirecting etc.
if (user == null) return;
// we're done then.
if (user is IUser) return;
var userEntity = IoC.Resolve<IUserRepository>().FindByUserName(user.Identity.Name);
// we can't find the user in the database.
if (userEntity == null)
throw new ApplicationException(string.Format("User \"{0}\" deleted from, or renamed in, database while logged into application.",
user.Identity.Name));
// signed in, assigning user, which should assign Thread.CurrentPrincipal as well (it wouldn't do this on PostAuthenticateRequest).
app.Context.User = new UserPrincipal(userEntity);
userEntity.SetAuthenticated();
}
//Implement IDisposable.
public void Dispose()
{
}
}
If your UserPrincipal implements IPrincipal, then IsInRole is used to give role-based access to your pages.
The principle that you follow is that if something is not allowed in a web application you do throw new HttpException(405, "The current operation you are trying to perform is now allowed for your role or user or chosen path in life")
in the AuthorizeRequest event. Note that there's a AuthenticateRequest and another AuthorizeRequest event
Upvotes: 1
Reputation: 1179
Henrik's answer is a good one and should work if properly implemented. However, this is another option which tackles the problem more from a configuration standpoint. I know that you mentioned that you won't know the page names ahead of time so you can't include an entry in web.config for each page BUT web.config allows you to secure folders too. You could have all pages that require authentication placed in a folder called "AuthRequired" and all pages that don't require authentication placed in a folder called "Anonymous", for example. Then in your web config you could have the following entries:
<location path="AuthRequired">
<system.web>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
</system.web>
</location>
<location path="Anonymous">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
Upvotes: 3