[WCF權限控製]WCF自定義授權體係詳解[原理篇]
到目前為止,我麼介紹的授權策略都是圍繞著安全主體進行的,基本上都是基於角色的授權。雖然角色是定義權限最為常用的形式,但是它解決不了授權的所有問題。基於角色的授權策略一般是這樣的:。那麼假設我們的授權策略是這樣的:訪問權限和兩個角色進行關聯,訪問者需要同時被分配了這兩個角色才能被授權。這是一個很常見的授權策略,但是典型的基於單一角色的授權解決不了這個問題(除非為兩個角色的交集創建新的角色)。而這僅僅是一種簡單的授權策略,有時候授權需要通過一個複雜的表達式來表示,而且其中會涉及諸多元素,比如身份、角色和組織等。
我之所以說這麼多,主要是為說明一個問題:。而作為一種基於可擴展性的通信框架,WCF在授權方麵提供了擴展點,使你可以根據的你實際需要定製相應的授權策略。WCF為了創建了一個基於“聲明”的授權係統,為了讓讀者對該係統的內部原理有全麵的了解,我們不妨先來討論一下這裏指的聲明是如何定義的。
目錄:
一、Claim和ClaimSet
二、DispatchRuntime中的AuthorizationPolicy和ServiceAuthorizationManager
三、通過自定義AuthorizationPolicy創建基於自定義授權策略的聲明
四、通過自定義ServiceAuthorizationManager根據聲明作出最後的授權判斷
聲明描述了與係統中某個實體關聯的功能,該實體通常為該係統中的某個用戶。通過對訪問給定的受保護資源所需的聲明和與試圖進行訪問的實體關聯的聲明進行比較,便可確定該資源的訪問權限。聲明是針對特定值的權限表達式。權限可以是讀取、寫入或擁有。值可以是數據庫、文件、郵箱或屬性。聲明還具有聲明類型。聲明類型和權限的組合提供了用於針對該值指定的功能的機製。在WCF安全應用編程接口中,生命通過類型Claim表示。從下麵給出的關於Claim定義的代碼片斷中,我們可以認識到:一個通過Claim對象表示的聲明具有如下三要素:、和。
1: public class Claim
2: {
3: //其他成員
4: public string ClaimType { get; }
5: public object Resource { get; }
6: public string Right { get; }
7: }
通過Right屬性表示的權限類型一般通過一個統一資源標識符(URI)來表示,而靜態類Rights定義了兩個預定義的權限類型:Identity和PossessProperty。前者表示聲明用於身份標識,後者則表示聲明關聯的實體具有的屬性。Rights類定義如下。
1: public static class Rights
2: {
3: public static string Identity { get; }
4: public static string PossessProperty { get; }
5: }
在上麵我們已經提到過了,借助於WCF的擴展,我們通過自定義AuthorizationPolicy和ServiceAuthorizationManager來讓WCF按照我們自定義的授權策略進行訪問控製。那麼。這兩個對象是如何參與到WCF的授權執行流程中的呢?
我們首先需要了解的是:自定義的AuthorizationPolicy和ServiceAuthorizationManager通過服務行為ServiceAuthorizationBehavior成為WCF運行時的一部分。具體來說,在ServiceAuthorizationBehavior的ApplyDispatchBehavior方法被調用的時候,定義在ExternalAuthorizationPolicies屬性中的AuthorizationPolicy列表和ServiceAuthorizationManager被賦值給所有終結點的分發運行時。在DispatchRuntime類型中,具有兩個同名的屬性。
1: public sealed class DispatchRuntime
2: {
3: //其他成員
4: public ReadOnlyCollection<IAuthorizationPolicy> ExternalAuthorizationPolicies { get; set; }
5: public ServiceAuthorizationManager ServiceAuthorizationManager { get; set; }
6: }
整個自定義授權先從AuthorizationPolicy開始。具體來說,WCF先創建一個EvaluationContext對象。我們之前隻提到過EvaluationContext用於表示屬性的Properties,實際上它的核心是通過屬性表示的聲明集(ClaimSet)的集合。下麵給出的EvaluationContext的整個公用成員的定義,除了Properties和ClaimSets之前,EvaluationContext還具有一個額外的屬性Generation表示聲明集被添加到ClaimSets集合的次數。而聲明集的添加通過方法AddClaimSet實現。EvaluationContext具有一個有效性,而失效的時間可以通過方法RecordExpirationTime來記錄。
1: public abstract class EvaluationContext
2: {
3: public abstract void AddClaimSet(IAuthorizationPolicy policy, ClaimSet claimSet);
4: public abstract void RecordExpirationTime(DateTime expirationTime);
5:
6: public abstract ReadOnlyCollection<ClaimSet> ClaimSets { get; }
7: public abstract int Generation { get; }
8: public abstract IDictionary<string, object> Properties { get; }
9: }
EvaluationContext是一個抽象類型,實際被創建的是一個被稱為System.IdentityModel.Policy.DefaultEvaluationContext的內部類型的對象。。一般地,我們通過自定義AuthorizationPolicy的目的在於通過在實現的Evaluate方法中將基於你自定義授權策略相關的聲明集添加到EvaluationContext的ClaimSets中。
在所有的自定義AuthorizationPolicy的Evaluate方法被調用之後,最終的EvaluationContext對象被用以初始化當前的授權上下文()。下麵給出了AuthorizationContext的所有公共屬性的定義。一般來說,除了Id,其餘三個屬性直接來源於EvaluationContext。具體來說,EvaluationContext的ClaimSets和Properties作為AuthorizationContext的ClaimSets和Properties,而EvaluationContext通過RecordExpirationTime記錄的過期時間反應在AuthorizationContext的ExpirationTime上。
1: public abstract class AuthorizationContext : IAuthorizationComponent
2: {
3: public abstract string Id { get; }
4:
5: public abstract ReadOnlyCollection<ClaimSet> ClaimSets { get; }
6: public abstract DateTime ExpirationTime { get; }
7: public abstract IDictionary<string, object> Properties { get; }
8: }
和EvaluationContext一樣,AuthorizationContext也是一個抽象類,默認被創建的是一個名稱為System.IdentityModel.Policy.DefaultAuthorizationContext的內部類型對象。。具體來說,WCF通過調用ServiceAuthorizationManager的CheckAccess方法決定當前操作是否被授權訪問。
為了讓自定義授權有深刻的理解,在《實例篇》中我們將演示一個簡單的實例為你展示如何通過自定義AuthorizationPolicy和ServiceAuthorizationManager實現,敬請期待。
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
最後更新:2017-10-26 16:05:16