4

私は現在、asp.netの標準ページ認証構成の代替ソリューションを調査しています。

同じアクセスポリシーを必要とするファイルのディレクトリがある場合、ロケーションタグは問題なく機能しますが、個別のアクセスポリシーが多数ある場合、ロケーションタグは面倒です。私は自分のカスタム認証システムをロールすることができましたが、それを避けることができればそれはおそらくより良いでしょう。

現在、ページコンテンツにazmanのような権限ベースの承認システムを使用していますが、これを標準のページセキュリティと統合する良い方法はまだ見つかりません。

これを行う方法について何か提案はありますか?azmanとasp.netページ認証を統合するソリューションはありますか?私が知っておくべき他の標準的な解決策はありますか?

4

3 に答える 3

6

私は、次のようなさまざまな権限とさまざまな役割を持つ巨大なアプリケーションで実行しました[ここにはコードがないので、ここで再作成してみます]:

私は最初に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必要があるアクセス許可であり、ユーザーがページにアクセスするためにそれらの少なくとも1つを必要とするアクセス許可です。オプションがあるかどうかは関係ないので、すべてのページで両方を使用する必要はありMandatoryPermissionsません。

許可は列挙型です:


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

}

そしてMyUser、の実装です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
        //
    }
}

次に、ページで行う必要があるのは、権限リストにデータを入力することだけです。


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、検索例はそれほど良くありませんでしたが、私はあなたが写真を撮ったと思います。

全体的な考え方はbase.OnLoad(e);、アクセス許可の検証の直前に呼び出されるため、にアクセス許可を入力するだけですPage_Load

これが最善の解決策かどうかはわかりませんが、大いに役立つと確信しています:)

于 2009-04-25T03:52:24.613 に答える
1

ページをデータベース内のロールにマッピングしてから、マスターページにページロード時にDBをチェックさせるのはどうですか?

于 2009-07-08T11:05:38.887 に答える
0

アプリケーションの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

うまくいけば、これはあなたがそれをあなたの環境に形作るために必要なものをあなたに与えるでしょう。

于 2009-04-24T22:17:57.507 に答える