簡體   English   中英

ASP.NET頁面授權......你是怎么做到的?

[英]ASP.NET Page Authorization… How do you do it?

我目前正在研究asp.net中標准頁面授權配置的替代解決方案。

如果您的文件目錄需要相同的訪問策略,但是如果您有許多單獨的訪問策略,則位置標記很難處理。 我可以滾動我自己的自定義身份驗證系統,但如果可以避免那可能更好。

目前我們正在為頁面內容使用類似azman的權限授權系統,但我還沒有找到將其與標准頁面安全性集成的好方法。

有關如何做到這一點的任何建議? 有沒有集成azman和asp.net頁面授權的解決方案? 我應該注意哪些其他標准解決方案?

我在一個巨大的應用程序中做了很多不同的權限和不同的角色,如下所示[我沒有這里的代碼所以我只是嘗試在這里重新創建]:

我首先實現了一個名為SecuredPage的類,如下所示:


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

對於用戶需要訪問權限的所有頁面,這將是我的BasePage。 MandatoryPermissions是用戶必須擁有訪問頁面的權限,而OptionalPermissions是用戶至少需要其中一個訪問頁面的權限。 沒有必要在每個頁面上同時使用這兩個頁面,因為如果您有MandatoryPermissions則無論您是否擁有選項都無關緊要。

許可是一個枚舉:


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

}

MyUserMembershipUser一個實現:


public class MyUser : System.Web.Security.MembershipUser
{
    internal bool HasPermission(Permission permission)
    {
        //
        // TODO: Check on database if the user has the permission or not
        //
    }
}

然后,您在頁面中唯一需要做的就是填充權限列表:


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

好的,搜索示例不是那么好,但我認為你得到了圖片。

整個想法是base.OnLoad(e); 在權限驗證之前調用,因此您只需要填寫Page_Load的權限。

我不確定這是否是最佳解決方案,但我確信它有很大幫助:)

如何將頁面映射到數據庫中的角色,然后讓您的母版頁檢查頁面上的數據庫?

您是否在應用程序的Application_AuthenticateRequest方法中設置了GenericIdentity和IPrincipal對象?

我們目前使用我們的域在SQL Server數據庫上執行身份驗證和用戶組/角色以提供授權。 在Application_AuthenticateRequest方法期間,我收集所有這些數據並基於它創建FormsAuthenticationTicket對象。

通過這樣做,我現在可以通過在我的代碼中執行簡單的User.IsInRole(“RoleX”)命令來訪問用戶的角色,這使我可以輕松鎖定/解鎖用戶控件,甚至可以執行簡單的Response.Redirect()如果他們沒有適當的授權,請到“授權錯誤”頁面。

這是我的AuthenticateRequest方法的樣子(VB.NET)

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

......同樣,這是CustomPrincipal對象的樣子:

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's 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

希望這能為您提供將其塑造成環境所需的一切。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM