I did in a huge application having lots of different permissions and different roles something like the following [I don't have the code here so I'll just try to recreate it here]:
I first implemented a class called SecuredPage as following:
public class SecuredPage : System.Web.UI.Page
{
// Those Permissions are mandatory, so user needs to have all of them
public List MandatoryPermissions { get; set; }
// Those Permissions are optional, so if the user have at least one of them, he can access
public List OptionalPermissions { get; set; }
protected override void OnLoad(EventArgs e)
{
MyUser loggedUser = (MyUser) this.User;
base.OnLoad(e);
foreach (Permission mandatoryPermission in MandatoryPermissions)
{
// if the user don't have permission, we can redirect him
if (!loggedUser.HasPermission(mandatoryPermission))
{
RedirectToDontHaveAccess();
break;
}
}
bool hasAccessToThePage = false;
foreach (Permission optionalPermission in OptionalPermissions)
{
// If the user has at least one of the permissions, he can access
if (loggedUser.HasPermission(optionalPermission))
{
hasAccessToThePage = true;
}
}
if (!hasAccessToThePage)
{
RedirectToDontHaveAccess();
}
}
private void RedirectToDontHaveAccess()
{
throw new NotImplementedException();
}
}
This will be my BasePage for all pages that user need permissions to access.
The MandatoryPermissions
are permissions that user MUST have all of them to access the page and OptionalPermissions
are permissions that user needs at least one of them to access the page.
There's no need to use both on every page because if you have MandatoryPermissions
doesn't matter if you have the optionals or not.
Permission is a enum:
public enum Permission
{
// Usually this enum will replicate a domain table from the database
EditUser = 1,
SearchUserByUsername = 2,
SearchUserByEmail = 3
}
And MyUser
is a implementation of MembershipUser
:
public class MyUser : System.Web.Security.MembershipUser
{
internal bool HasPermission(Permission permission)
{
//
// TODO: Check on database if the user has the permission or not
//
}
}
Then the only thing that you need to do in your pages is to populate the permissions lists:
public partial class EditUser : SecuredPage
{
protected void Page_Load(object sender, EventArgs e)
{
MandatoryPermissions.Add(Permission.EditUser);
}
}
public partial class SearchUser : SecuredPage
{
protected void Page_Load(object sender, EventArgs e)
{
OptionalPermissions.Add(Permission.SearchUserByUsername);
OptionalPermissions.Add(Permission.SearchUserByEmail);
}
}
OK, the search example wasn't that good but I think you get the picture.
The whole idea is that base.OnLoad(e);
is called just before the permissions verification, so you just need to fill the permissions in your Page_Load
.
I'm not sure if this is the best solution but I'm sure it helps a lot :)