2011-09-02 71 views
1

我打算使用基於CodeAccessSecurity的基於自定義許可的聲明式授權機制。爲了實現它,我已經創建了從0​​得出以下子類:WCF使用CodeAccessSecurity的聲明式安全

[Serializable] 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] 
public class RequirePermissionAttribute : CodeAccessSecurityAttribute { 

    private static readonly IPermission _deny = new SecurityPermission(PermissionState.None); 
    private static readonly IPermission _allow = new SecurityPermission(PermissionState.Unrestricted); 

    public RequirePermissionAttribute(SecurityAction action) 
     : base(action) { 
    } 

    public string Permission { get; set; } 

    public override IPermission CreatePermission() { 
     if (User.HasPermission(Permission)) 
      return _allow; 
     else 
      return _deny; 
    } 
} 

我使用這種方式:

[ServiceContract] 
public class Service { 

    [OperationContract] 
    [RequirePermission(SecurityAction.Demand, Permission = "GetArbitaryProduct")] 
    public User GetProduct(string name) { 
     return _productRepository.Get(name); 
    } 
} 

而且我預計,如果CreatePermission方法返回_deny訪問GetProduct將被限制。但它看起來CodeAccessSecurity不這樣工作。我是否必須拋出異常來正確限制訪問?或者,也許有更優雅的方式來實現呢?

回答

1

基於CodeAccessSecurityAttribute子類實例連接權限驗證的CLR機制只會在評估由CreatePermission()返回的權限時引發異常時阻止目標方法的執行。由於您將SecurityAction.Demand指定爲權限操作,這意味着權限的Demand()方法必須拋出以避免執行目標方法。

還有很多其他的方式來處理授權方案,其中很多您可能會發現更多的「優雅」。但是,在開始尋找替代方法之前,最好考慮拒絕授權時服務調用方應該遵守的行爲。你是否希望該方法成功,但返回null,還是希望返回錯誤?如果是後者,你是否希望它成爲打字錯誤?

+0

目前,沒關係,我對呼叫者沒有任何要求,所以我可以自由實現它,因爲我想。但我認爲這種類型的錯誤是首選。 – sam

+0

如果您更喜歡鍵入的錯誤,那麼使用允許您拋出SecurityException的默認路由可能是最簡單的方法。這將導致WCF內部自動生成映射到WCF客戶端中的SecurityAccessDeniedException的錯誤(http://msdn.microsoft.com/en-us/magazine/cc948343.aspx#id0070004)。 –