[WCF權限控製]ASP.NET Roles授權[上篇]
在采用Windows認證的情況下,使用基於Windows用戶組安全主體權限模式是一個不錯的選擇。我們可以直接使用現有的用戶組設置,也可以為相應的應用或服務創建單獨的用戶組。但是,由於該模式對Windows認證的依賴,意味著這種模式隻能使用於局域網環境中。如果采用證書和Windows帳號的映射,也可以適用於像B2B這樣的外部網環境。在其他的網絡環境中,基於Windows用戶組的授權方式將會無能為力。此外,還具有這樣一種狀況:即使是在同一個局域網環境中,並且也采用Windows進行客戶端認證,但是我們不想創建太多的Windows用戶組,而是將用戶的權限信息維護在相應的數據庫中,通過單獨的安全係統來維護。在這種情況下,基於ASP.NET角色管理模塊的授權模式是一個不錯的選擇。
目錄:
一、 ASP.NET Roles提供程序
二、 ASP.NET Roles授權與認證的無關性
三、 ASP.NET Roles授權 在ServiceAuthorizationBehavior中的設定
和Membership一樣,Roles也是ASP.NET一個重要的提供程序,旨在解決對角色的維護和基於角色的授權。ASP.NET Roles同樣采用策略設計模式,角色的添加、刪除、獲取以及授權功能定義在System.Web.Security.RoleProvider這個抽象類中。而ASP.NET默認提供了如下三個具體的RoleProvider,它們同時也體現了角色和授權信息的三種不同的存儲形式。如果它們還不能滿足你的具體授權要求,你還可以自定義RoleProvider。比如說,如果你使用的數據庫是Oracle,你可以參考SqlRoleProvider自定義一個OracleRoleProvider。
- SqlRoleProvider:將角色和授權信息存儲於SQL Server數據庫預定義的表中;
- WindowsTokenRoleProvider:直接使用Windows用戶組進行授權,這是一個隻讀的RoleProvider,角色(用戶組)的添加和刪除操作是不允許的;
- AuthorizationStoreRoleProvider:使用Authorization Manager(AzMan)庫做作為角色存儲。
ASP.NET Roles相關的功能基本上都可以通過調用Roles這個靜態類的相應的方法來完成。下麵的代碼片斷列出了Roles的主要方法。其中CreateRole和DeleteRole用於進行角色創建和刪除;RoleExists用戶確定指定的角色是否存在;而AddUser(s)ToRole(s)和RemoveUser(s)FromRole(s)則用以建立和解除用戶和角色的關係。而IsUserInRole用以確定指定的用戶具有相應的角色。
1: public static class Roles
2: {
3: //其他成員
4: public static void CreateRole(string roleName);
5: public static bool DeleteRole(string roleName);
6: public static bool DeleteRole(string roleName, bool throwOnPopulatedRole);
7: public static bool RoleExists(string roleName);
8:
9: public static void AddUsersToRole(string[] usernames, string roleName);
10: public static void AddUsersToRoles(string[] usernames, string[] roleNames);
11: public static void AddUserToRole(string username, string roleName);
12: public static void AddUserToRoles(string username, string[] roleNames);
13:
14: public static void RemoveUserFromRole(string username, string roleName);
15: public static void RemoveUserFromRoles(string username, string[] roleNames);
16: public static void RemoveUsersFromRole(string[] usernames, string roleName);
17: public static void RemoveUsersFromRoles(string[] usernames, string[] roleNames);
18:
19: public static bool IsUserInRole(string roleName);
20: public static bool IsUserInRole(string username, string roleName);
21: }
針對Roles的方法AddUser(s)ToRole(s),有一點值得一提:。原因很簡單,用戶賬號的管理屬於Membership的範疇,而建立用戶與角色的關係才是屬於角色管理需要負責的。Membership和Roles對於ASP.NET是相互獨立的兩個提供程序,它們不具有任何依賴關係。你完全可以采用ActiveDirectoryMembershipProvider利用AD進行用戶賬號管理和認證,而采用將角色維護在基於SqlRoleProvider的SQL Server數據表中。在這著情況下,當我們調用Roles的AddUser(s)ToRole(s)方法的時候,指定的用戶帳號在數據庫中是不存在的。所以,Roles不會進行用戶存在與否的驗證,它隻是負責將指定的用戶名添加到相應的角色之中而以。Membership和Roles的這種獨立性同樣體現在WCF上。
通過前麵的介紹我們很清楚地知道了Windows用戶組授權依賴於Windows認證,但是如果你采用了ASP.NET Roles安全主體權限模式,你可以采用任何非匿名客戶端憑證和認證方式。也就是說,。
在采用ASP.NET Roles安全主體權限模式下,最終創建並作為當前線程安全主體的是一個RoleProviderPrincipal對象。而該RoleProviderPrincipal的Identity與當前ServiceSecurityContext的PrimaryIdentity屬性實際上是同一個對象。兩者的統一性可以通過於如下的驗證程序來體現。
1: IIdentity identity1 = Thread.CurrentPrincipal.Identity;
2: IIdentity identity2 = ServiceSecurityContext.Current.PrimaryIdentity;
3: Debug.Assert(object.ReferenceEquals(identity1,identity2));
原則上,隻要通過本認證的用戶名能夠通過ASP.NET Roles正確獲取到反映權限的角色列表,授權就能順利進行。如果采用Windows認證(包括之前提到的三種情況),你需要針對Windows帳號(域名/用戶名)進行角色分配。如果采用基於Membership和Custom的用戶名/密碼認證,則直接針對用戶名角色的分配。如果采用證書憑證並不允許Windows帳號映射,那麼被認證的用戶名是證書主體名稱和指紋的組合(),你需要以此進行權限(角色)的設置。
之前已經說過了,所有基於安全主體授權的編程都體現在ServiceAuthorizationBehavior這個服務行為上。如果要讓WCF采用ASP.NET Roles進行授權,我們需要將ServiceAuthorizationBehavior的PrincipalPermissionMode屬性設置成PrincipalPermissionMode.UseAspNetRoles,並為其RoleProvider屬性指定一個具體的RoleProvider。至於RoleProvider的獲取,你可以通過Roles的Provider得到默認的RoleProvider。此外,Roles還具有一個類似於字典類型的Providers屬性返回所有配置的RoleProvider列表,你可以通過傳入配置名稱獲取相應的RoleProvider。
1: public sealed class ServiceAuthorizationBehavior : IServiceBehavior
2: {
3: //其他成員
4: public PrincipalPermissionMode PrincipalPermissionMode { get; set; }
5: public RoleProvider RoleProvider { get; set; }
6: }
7: public static class Roles
8: {
9: //其他成員
10: public static RoleProvider Provider { get; }
11: public static RoleProviderCollection Providers { get; }
12: }
下麵給出的是一段基於自我寄宿的代碼。在開啟ServiceHost之前,我們為服務指定了一個ServiceAuthorizationBehavior行為,並將其安全主體權限模式設置成PrincipalPermissionMode.UseAspNetRoles,該ServiceAuthorizationBehavior使用當前配置的默認RoleProvider。
1: using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
2: {
3: host.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.UseAspNetRoles;
4: host.Authorization.RoleProvider = Roles.Provider
5: host.Open();
6: //...
7: }
我們還是一如既往地推薦采用配置的方式進行服務授權的設置。在下麵這段配置中,我們在<system.web>/<roleManager>節點下配置了一個唯一的類型為SqlRoleProvider的RoleProvider。該SqlRoleProvider的配置名稱為sqlRoleProvider,而目標數據庫對應的連接字符串名稱為aspNetDb。而ServiceAuthorizationBehavior配置在名稱為aspNetRolesAuthorization的服務行為配置節中,反映其安全主體權限模式的principalPermissionMode屬性被設置成UseAspNetRoles,而roleProviderName屬性則正是配置的RoleProvider的名稱。
1: <configuration>
2: <connectionStrings>
3: <add name="aspNetDb" connectionString="..." providerName="System.Data.SqlClient"/>
4: </connectionStrings>
5: <system.web>
6: <roleManager enabled="true" defaultProvider="SqlRoleProvider">
7: <providers>
8: <add name="sqlRoleProvider"
9: type="System.Web.Security.SqlRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
10: connectionStringName="aspNetDb" applicationName="AspRolesAuthorizationDemo"/>
11: </providers>
12: </roleManager>
13: </system.web>
14: <system.serviceModel>
15: <services>
16: <service name="Artech.WcfServices.Services.CalculatorService" behaviorConfiguration="aspNetRolesAuthorization">
17: <endpoint address="https://127.0.0.1/calculatorservice" binding="ws2007HttpBinding"
18: contract="Artech.WcfServices.Contracts.ICalculator"/>
19: </service>
20: </services>
21: <behaviors>
22: <serviceBehaviors>
23: <behavior name="aspNetRolesAuthorization">
24: <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="sqlRoleProvider"/>
25: </behavior>
26: </serviceBehaviors>
27: </behaviors>
28: </system.serviceModel>
29: </configuration>
為了讓讀者對基於ASP.ENT Roles授權方式有一個全麵的認識,我們將在《下篇》做一個具體的實例演示,敬請期待。
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
最後更新:2017-10-26 16:34:03