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授权[下篇]

  • 相关阅读:
    leetcode 48. Rotate Image
    leetcode 203. Remove Linked List Elements 、83. Remove Duplicates from Sorted List 、82. Remove Duplicates from Sorted List II(剑指offer57 删除链表中重复的结点) 、26/80. Remove Duplicates from Sorted ArrayI、II
    leetcode 263. Ugly Number 、264. Ugly Number II 、313. Super Ugly Number 、204. Count Primes
    leetcode 58. Length of Last Word
    安卓操作的一些问题解决
    leetcode 378. Kth Smallest Element in a Sorted Matrix
    android studio Gradle Build速度加快方法
    禁用gridview,listview回弹或下拉悬停
    Android Studio找不到FragmentActivity类
    安卓获取ListView、GridView等滚动的距离(高度)
  • 原文地址:https://www.cnblogs.com/artech/p/asproles01.html
Copyright © 2011-2022 走看看