[WCF許可權控制]利用WCF自定義授權模式提供當前Principal[原理篇]
在《通過擴充套件自行實現服務授權》一文中,我通過自定義CallContextInitializer的方式在操作方法之前之前根據認證使用者設定了當前執行緒的安全主體,從而實現授權的目的。實際上,WCF的安全體系本就提供相應的擴充套件,使你能夠自由地實現安全主體的提供方式。具體來說,安全主體的提供可以通過自定AuthorizationPolicy或者ServiceAuthorizationManager來實現。
一、AuthorizationPolicy
在WCF安全應用程式設計介面中,所有的AuthorizationPolicy實現了IAuthorizationPolicy介面。如下面的程式碼所示,IAuthorizationPolicy繼承自IAuthorizationComponent介面,本身具有一個ClaimSet型別的Issuer屬性和一個Evaluate方法。關於ClaimSet,我們會在後續的部分繼續介紹,這裡我們只需要關注Evaluate方法。該方法的第一個引數的型別為System.IdentityModel.Policy.EvaluationContext,它具有一個字典型別的只讀屬性Properties。
1: public interface IAuthorizationPolicy : IAuthorizationComponent
2: {
3: bool Evaluate(EvaluationContext evaluationContext, ref object state);
4: ClaimSet Issuer { get; }
5: }
6: public abstract class EvaluationContext
7: {
8: //其他成員
9: public abstract IDictionary<string, object> Properties { get; }
10: }
如果我們需要通過自定義的方式來提供安全主體,我們只需要通過實現IAuthorizationPolicy介面建立自定義的AuthorizationPolicy,並在Evaluate方法中將建立安全主體物件新增到EvaluationContext的Properties字典中即可。在該字典中,用於存放安全主體條目對應的鍵值為“Principal”。
1: Public class CustomAuthorizationPolicy:IAuthorizationPolicy
2: {
3: //其他成員
4: bool Evaluate(EvaluationContext evaluationContext, ref object state)
5: {
6: //其他操作
7: evaluationContext. Properties[“Principal”] = customPrincipal;
8: return true;
9: }
10: }
那麼自定義的AuthorizationPolicy通過怎樣的方式被應用到WCF的授權執行時呢?這還是要藉助於我們已經很熟悉的服務行為ServiceAuthorizationBehavior。如下面給出的程式碼片斷所示,ServiceAuthorizationBehavior具有一個型別為ReadOnlyCollection<IAuthorizationPolicy>
的ExternalAuthorizationPolicies屬性,表示自定義AuthorizationPolicy的集合。
1: public sealed class ServiceAuthorizationBehavior : IServiceBehavior
2: {
3: //其他成員
4: public ReadOnlyCollection<IAuthorizationPolicy> ExternalAuthorizationPolicies { get; set; }
5: }
你可以通過程式設計的方式將自定義的AuthorizationPolicy新增到ServiceAuthorizationBehavior的ExternalAuthorizationPolicies集合中,也可以通過配置指定自定義AuthorizationPolicy的型別。如下面給出的配置片斷所示,ServiceAuthorizationBehavior的ExternalAuthorizationPolicies集合對應的配置節點為<serviceAuthorization>/<authorizationPolicies>。
1: <configuration>
2: <system.serviceModel>
3: <behaviors>
4: <serviceBehaviors>
5: <behavior name="useCustomAuthorization">
6: <serviceAuthorization principalPermissionMode="Custom">
7: <authorizationPolicies >
8: <add policyType="AuthorizationPolicyType1" />
9: <add policyType="AuthorizationPolicyType2" />
10: ...
11: </authorizationPolicies>
12: </serviceAuthorization>
13: <serviceDebug includeExceptionDetailInFaults="true"/>
14: </behavior>
15: </serviceBehaviors>
16: </behaviors>
17: </system.serviceModel>
18: </configuration>
二、ServiceAuthorizationManager
在ServiceAuthorizationBehavior選擇Custom安全主體許可權模式的情況下,除了自定義AuthorizationPolicy,你還可以通過自定義ServiceAuthorizationManager來提供當前的安全主體。下面給出了ServiceAuthorizationManager的定義,從中我們可以看出它具有兩個CheckAccess方法用於實現授權。方法的返回值表示當前請求的服務操作是否被授權指定。實際上最終的授權判斷實現在受保護方法CheckAccessCore中,並且在ServiceAuthorizationManager中該方法直接返回True。
1: public class ServiceAuthorizationManager
2: {
3: //其他成員
4: public virtual bool CheckAccess(OperationContext operationContext);
5: public virtual bool CheckAccess(OperationContext operationContext, ref Message message);
6: protected virtual bool CheckAccessCore(OperationContext operationContext);
7: }
當ServiceAuthorizationBehavior的PrincipalPermissionMode被設定成Custom的情況下,被設定的當前安全主體實際上是通過當前服務安全上下文(ServiceSecurityContext)獲取的。具體來說,ServiceSecurityContext具有一個表示授權資訊的AuthorizationContext物件。和EvaluationContext一樣,AuthorizationContext也具有一個字典型別的Properties屬性。實際上,通過AuthorizationPolicy新增到EvaluationContext中的屬性,最終都會被轉移到當前AuthorizationContext的Properties屬性中。
1: public class ServiceSecurityContext
2: {
3: //其他成員
4: public AuthorizationContext AuthorizationContext { get; }
5: }
6: public abstract class AuthorizationContext : IAuthorizationComponent
7: {
8: //其他成員
9: public abstract IDictionary<string, object> Properties { get; }
10: }
所以只要我們能夠在WCF從當前AuthorizationContext獲取安全主體之前對其進行初始化,整個基於安全主體的授權體系就能正常運作,而這個工作可以通過自定義ServiceAuthorizationManager來實現。一般來講,我們只需通過繼承ServiceAuthorizationManager,重寫虛方法CheckAccessCore進行安全主體的初始化。
1: public class CustomServiceAuthorizationManager : ServiceAuthorizationManager
2: {
3: protected override bool CheckAccessCore(OperationContext operationContext)
4: {
5: //其他操作
6: AuthorizationContext authorizationContext = operationContext.ServiceSecurityContext.AuthorizationContext;
7: authorizationContext.Properties["Principal"] = customPrincipal;
8: return true;
9: }
10: }
自定義的ServiceAuthorizationManager最終還是通過ServiceAuthorizationBehavior這個服務行為應用到WCF授權框架體系中。如下面給出的程式碼片斷所示,在ServiceAuthorizationBehavior中依然具有相應屬性定義的。而在ServiceAuthorizationBehavior的配置節中,ServiceAuthorizationManager對應的配置屬性為serviceAuthorizationManager,你可以通過該配置屬性將設定自定義ServiceAuthorizationManager的型別。
1: public sealed class ServiceAuthorizationBehavior: IServiceBehavior
2: {
3: //其他成員
4: public ServiceAuthorizationManager ServiceAuthorizationManager { get; set; }
5: }
如果兩種預設的安全主體許可權模式(UseWindowsGroup和UseAspNetRoles)不能滿足你的要求,你需要自定義安全主體提供方式,自定義AuthorizationPolicy或者ServiceAuthorizationManager不失為一個很好的解決方案。為了讓你對此有個深刻的認識,在《下篇》中我們提供一個完整的例項。
[WCF許可權控制]利用WCF自定義授權模式提供當前安全主體[原理篇]
[WCF許可權控制]利用WCF自定義授權模式提供當前安全主體[例項篇]
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的訊息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。
相關文章
- [WCF許可權控制]利用WCF自定義授權模式提供當前Principal模式
- [WCF許可權控制]透過擴充套件自行實現服務授權套件
- [WCF許可權控制]基於Windows使用者組的授權方式[上篇]Windows
- [WCF許可權控制]通過擴充套件自行實現服務授權[提供原始碼下載]套件原始碼
- [WCF許可權控制]從兩個重要的概念談起:Identity與Principal[下篇]IDE
- 自定義許可權物件物件
- Vue2-利用自定義指令實現按鈕許可權控制Vue
- hadoop自定義許可權Hadoop
- SAP自定義許可權物件物件
- android動態許可權到自定義許可權框架Android框架
- DRF內建許可權元件之自定義許可權管理類元件
- Django(63)drf許可權原始碼分析與自定義許可權Django原始碼
- DB2許可權與授權DB2
- Vue | 自定義指令和動態路由實現許可權控制Vue路由
- 授權物件許可權後的授權者顯示問題物件
- 如何用 Vue 實現前端許可權控制(路由許可權 + 檢視許可權 + 請求許可權)Vue前端路由
- Elasticsearch 許可權控制Elasticsearch
- 授權許可權服務設計解析
- android自定義訪問許可權permissionAndroid訪問許可權
- android framework中新增自定義許可權AndroidFramework
- 基於VUE自定義指令實現按鈕級許可權控制Vue
- 1.7.6. 授權和撤銷管理許可權
- 為什麼許可權授權很難?- osohq
- 許可權管理之多租戶隔離授權
- 認證/授權與許可權的問題
- SpringSecurity:hasAuthority與自定義許可權校驗SpringGse
- Linux許可權控制Linux
- Appfuse:許可權控制APP
- django開發之許可權管理(一)——許可權管理詳解(許可權管理原理以及方案)、不使用許可權框架的原始授權方式詳解Django框架
- jenkins原理篇——成員許可權管理Jenkins
- Think Authz:支援 ACL、RBAC、ABAC 等模型的授權(角色和許可權控制)庫模型
- .NET 程式許可權控制、獲得管理員許可權程式碼
- android - 解決“應用自定義許可權重名”Android
- 自定義Android應用的訪問許可權Android訪問許可權
- 認證鑑權與API許可權控制在微服務架構中的設計與實現:授權碼模式API微服務架構模式
- Laravel實現許可權控制Laravel
- mysql 許可權控制筆記MySql筆記
- oracle列級許可權控制Oracle