ASP.NET page authorization ... How do you do this?

I am currently studying alternative solutions to the standard page authorization configuration in asp.net.

The location tag works fine if you have file directories that require the same access policy, but if you have many access policies, the location tag is a pain. I could collapse my own auth system, but if it can be avoided, maybe better.

We currently use the Azman-based authorization system for the contents of the page, but I have not found a good way to integrate it with standard page protection.

Any suggestions on how to do this? Are there any solutions integrating azman and asp.net authorization? Are there any other standard solutions that I should be aware of?

+4
source share
3 answers

I did in a huge application that has many different permissions and different roles, something like the following [I don't have code here, so I'll just try to recreate it here):

First I implemented the SecuredPage class as follows:

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 for which the user needs permissions to access. MandatoryPermissions are the permissions that the user MUST have to access the page, and OptionalPermissions are the permissions for which the user needs at least one of them to access the page. There is no need to use them on every page, because if you have MandatoryPermissions , it doesn’t matter if you have extra or not.

Permission is an enumeration:

 public enum Permission { // Usually this enum will replicate a domain table from the database EditUser = 1, SearchUserByUsername = 2, SearchUserByEmail = 3 } 

And MyUser is an 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 you need to do on your pages is to fill out the permission 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 was not so good, but I think you got the image.

The whole idea is that base.OnLoad(e); called just before access control, so you just need to fill out the permissions in Page_Load .

I'm not sure if this is the best solution, but I'm sure it helps :)

+6
source

How about mapping pages to roles in your database, and then let your main page check the database for pageload?

+1
source

Did you set the GenericIdentity and IPrincipal objects during your Application_AuthenticateRequest method of the application?

We are currently using our domain for authentication and user / role groups in the SQL Server database for authorization. During the Application_AuthenticateRequest method, I collect all this data and create a FormsAuthenticationTicket object based on it.

Thus, I now have access to user roles by executing a simple User.IsInRole ("RoleX") command in my code that allows me to easily lock / unlock user controls or even perform a simple response. Redirect () to the "Authorization Error" page if they do not have the correct authorization.

This is what my AuthenticateRequest (VB.NET) method looks like

 Sub Application_AuthenticateRequest(ByVal sender As Object, _ ByVal e As EventArgs) Dim formsAuthTicket As FormsAuthenticationTicket Dim httpCook As HttpCookie Dim objGenericIdentity As GenericIdentity Dim objMyAppPrincipal As CustomPrincipal Dim strRoles As String() httpCook = Context.Request.Cookies.Get("authCookieEAF") formsAuthTicket = FormsAuthentication.Decrypt(httpCook.Value) objGenericIdentity = New GenericIdentity(formsAuthTicket.Name) strRoles = formsAuthTicket.UserData.Split("|"c) objMyAppPrincipal = New CustomPrincipal(objGenericIdentity, strRoles) HttpContext.Current.User = objMyAppPrincipal End Sub 

... and similarly, the CustomPrincipal object looks like this:

 Public Class CustomPrincipal Implements IPrincipal ''' <summary> ''' Identity object of user. ''' </summary> ''' <remarks></remarks> Private m_identity As IIdentity ''' <summary> ''' Roles(s) a user is a part of. ''' </summary> ''' <remarks></remarks> Private m_roles As String() ''' <summary> ''' Name of user. ''' </summary> ''' <remarks></remarks> Private m_userId As String ''' <summary> ''' Gets/Sets the user name. ''' </summary> ''' <value>m_userId</value> ''' <returns>Current name of user.</returns> ''' <remarks></remarks> Public Property UserId() As String Get Return m_userId End Get Set(ByVal value As String) m_userId = value End Set End Property ''' <summary> ''' Gets the identity object of the user. ''' </summary> ''' <value>m_identity</value> ''' <returns>Current identity of user.</returns> ''' <remarks></remarks> Public ReadOnly Property Identity() As System.Security.Principal.IIdentity Implements System.Security.Principal.IPrincipal.Identity Get Return m_identity End Get End Property ''' <summary> ''' Full constructor. ''' </summary> ''' <param name="identity">Identity to use with Custom Principal.</param> ''' <param name="roles">Roles for user.</param> ''' <remarks>Identity object contains user name when building constructor.</remarks> Public Sub New(ByVal identity As IIdentity, ByVal roles As String()) m_identity = identity m_roles = New String(roles.Length) {} roles.CopyTo(m_roles, 0) Array.Sort(m_roles) m_userId = identity.Name End Sub ''' <summary> ''' Determines if the current user is in the role specified. ''' </summary> ''' <param name="role">Role to test against.</param> ''' <returns>Boolean variable indicating if role specified exists in user m_roles array.</returns> ''' <remarks></remarks> Public Function IsInRole(ByVal role As String) As Boolean Implements System.Security.Principal.IPrincipal.IsInRole Dim boolResults As Boolean If Array.BinarySearch(m_roles, role) >= 0 Then boolResults = True Else boolResults = False End If Return boolResults End Function End Class 

Hope this gives you what you need to put it in your environment.

0
source

All Articles