zoukankan      html  css  js  c++  java
  • [WCF权限控制]ASP.NET Roles授权[上篇]

    在采用Windows认证的情况下,使用基于Windows用户组安全主体权限模式是一个不错的选择。我们可以直接使用现有的用户组设置,也可以为相应的应用或服务创建单独的用户组。但是,由于该模式对Windows认证的依赖,意味着这种模式只能使用于局域网环境中。如果采用证书和Windows帐号的映射,也可以适用于像B2B这样的外部网环境。在其他的网络环境中,基于Windows用户组的授权方式将会无能为力。此外,还具有这样一种状况:即使是在同一个局域网环境中,并且也采用Windows进行客户端认证,但是我们不想创建太多的Windows用户组,而是将用户的权限信息维护在相应的数据库中,通过单独的安全系统来维护。在这种情况下,基于ASP.NET角色管理模块的授权模式是一个不错的选择。

    目录:
    一、 ASP.NET Roles提供程序
    二、 ASP.NET Roles授权与认证的无关性
    三、 ASP.NET Roles授权 在ServiceAuthorizationBehavior中的设定

    一、ASP.NET Roles提供程序

    和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上。

    二、ASP.NET Roles授权与认证的无关性

    通过前面的介绍我们很清楚地知道了Windows用户组授权依赖于Windows认证,但是如果你采用了ASP.NET Roles安全主体权限模式,你可以采用任何非匿名客户端凭证和认证方式。也就是说,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帐号映射,那么被认证的用户名是证书主体名称和指纹的组合(<<主题名称>>; <<指纹>>),你需要以此进行权限(角色)的设置。

    三、ASP.NET Roles授权 在ServiceAuthorizationBehavior中的设定

    之前已经说过了,所有基于安全主体授权的编程都体现在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="http://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授权方式有一个全面的认识,我们将在《下篇》做一个具体的实例演示,敬请期待。

    [WCF权限控制]ASP.NET Roles授权[上篇]
    [WCF权限控制]ASP.NET Roles授权[下篇]

  • 相关阅读:
    题目1202:排序------注意每个数字的后面都有空格
    题目1178:复数集合------------结构体的的比较,cmp()函数的错误让我WA了多次
    题目1041:Simple Sorting-------注意最后一个数字的处理
    题目1034:寻找大富翁---用了sort()函数,注意头文件;
    题目1415:不一样的循环队列------注意细节小地方循环队列注意%M;还有为什么M要加一!!!!!!!!!!!!!
    题目1342:寻找最长合法括号序列II---注意:不要求就近匹配,只要求( 在 )前面的任一个位置即可
    题目1398:移动次数-----最少移动的次数,那么相同的最大值越靠后越好,相同的最小值越靠前越好
    题目1375:陈博的完美主义(25分)----------------题目中对输入数字的长度有要求,所以输入字符串,用atoi()转换函数
    题目1363:欢乐斗地主------用数组计数的应用,注意1和2得排在最后,表示最大
    题目1174:查找第K小数-------qsort()可以直接对数组用;还有用unique(a,a+n);的,服!
  • 原文地址:https://www.cnblogs.com/artech/p/asproles01.html
Copyright © 2011-2022 走看看