2013-03-04 62 views
1

我已經編寫了一個自定義PrincipalPermissionAttribute,它使用AuthenticationService而不是Thread.CurrentPrincipal作爲PrincipalPermissionAttribute。如何使定製PrincipalPermissionAttribute處理用戶或角色更改

它按照我喜歡的方式工作,但如果用戶註銷並返回,或者用戶的角色發生更改,則屬性代碼不會再次被調用。我懷疑我沒有通知它需要重新檢查權限的屬性?在CreatePermission方法上設置的斷點只遇到一次。

屬性代碼是否只評估過一次?該屬性目前正在爲我的View的代碼隱藏裝飾一個按鈕的事件處理程序。

如果我改回我的方法來使用PrincipalPermissionAttribute,那麼它的確如我所期望的那樣工作,註銷並作爲用戶返回並且沒有正確的角色將引發我期望的SecurityException。我是否錯過了覆蓋物業?

[Serializable] 
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true, Inherited = false)] 
public sealed class RolePermissionAttribute : CodeAccessSecurityAttribute 
{ 
    private readonly PrincipalPermission _revoke = new PrincipalPermission(PermissionState.None); 
    private readonly PrincipalPermission _allow = new PrincipalPermission(PermissionState.Unrestricted); 
    private IList<string> _roles; 

    private readonly IAuthenticationService _authorisationService; 

    public RolePermissionAttribute(SecurityAction action) 
     : this(action, ServiceLocator.Current.GetInstance<IAuthenticationService>()) 
    { 
    } 

    public RolePermissionAttribute(SecurityAction action, IAuthenticationService authorisationService) 
     : base(action) 
    { 
     _authorisationService = authorisationService; 
    } 

    public string Roles { get; set; } 

    public bool Authenticated { get; set; } 

    public override IPermission CreatePermission() 
    { 
     _roles = (this.Roles ?? string.Empty).Split(',', ';') 
           .Select(s => s.Trim()) 
           .Where(s => s.Length > 0) 
           .Distinct() 
           .ToList(); 

     bool result = false; 

     if (_authorisationService != null) 
     { 
      var principal = _authorisationService.ClientSecurityPrincipal; 
      if (principal == null) 
      { 
       throw new SecurityException("Access Denied. You are not logged in"); 
      } 

      // If Authenticated is enforced then revoke if user is not authenticated 
      if (Authenticated && !_authorisationService.IsAuthenticated) 
      { 
       throw new SecurityException("Access Denied. You are not authenticated"); 
      } 

      // Allow if the principal is in any of the roles 
      result = _roles.Any(principal.IsInRole); 
      if (!result) 
      { 
       throw new SecurityException("Access Denied. You are not in an allowed Role"); 
      } 
     } 

     return result ? _allow : _revoke; 
    } 
} 

}

下面是與屬性

[RolePermission(SecurityAction.Demand, Authenticated = true, Roles = "Admin")] 
private void barButtonItemConfig_ItemClick(object sender, ItemClickEventArgs e) 
{ 
    // Do stuff 
} 
+0

您能否包含您添加到視圖的按鈕點擊處理程序的屬性的代碼? – 2013-03-04 20:55:20

回答

1

好,我想通了,它是如何工作的方法。 CreatePermission實際上只調用一次。返回的IPermission是用於檢查用戶是否處於所需角色的類。

由於我向用戶A返回了一個不受限制的允許,因此無論用戶B的角色如何,用戶B都獲得了相同的訪問權限。

我需要創建自己的類來實現IPermission並將我的邏輯移動到Demand方法中。或者(更簡單的選項)將我的服務中的委託人分配給Thread.CurrentPrincipal並使用開箱即可的PrincipalPermissionAttribute。

+3

如果你創建它,請給我們提供代碼,因爲我有類似的情況,但我需要創建更多的粒度級別(Permission-Role-User),並且我需要使PrincipalPermissionAttribute檢查Permission而不是Role,所以如果你有任何線索,將不勝感激 – 2014-06-15 07:34:24

+0

我有同樣的問題,你可以請看看這個; https://stackoverflow.com/questions/45770217/my-customauthorizationpolicy-evaluate-method-never-fires – 2017-08-21 07:28:48

相關問題