CommunityServer权限系统浅析
CommunityServer2.1的权限系统主要是基于ASP.NET 2.0的Membership来实现的, 应该说CS1.0就开始采用的Membership是最终成为微软官方产品的原型. Membership主要是基于User/Role的验证体系, 一个User可以具有多个Role角色, 同时在Web.Config文件中通过在authorization配置节中使用allow/deny元素可以简单地实现基于角色的权限控制. 这么做已经很大程度上简化了程序员的劳动, 可是仅仅做到基于角色的允许和拒绝访问还不够, 因为操作是多样化的, 比如对论坛就有着, 浏览/回复/投票/发表主题等多种权限, 这已经无法用简单的允许和拒绝来实现了, 显然必须在代码级别实现校验. 所以CS就引入了自己的Permission机制.
因为所有三种Application: Forum, Blog, Gallery都继承自Section这个基类, 但是针对各个不同类型Application的校验机制都不一样, 所以CS在这里就采用了Strategy模式, 为每种Application都实现了一个[ApplicationName]Permission的类(比如对应Forum就是ForumPermission), 每个Permission类都继承自PermissionBase基类, 在这个基类中声明了AccessCheckDelegate和ValidatePermissionsDelegate两个代理声明, 下面拿Forum举例校验过程, ForumPermission实现这两个代理的具体静态方法, 分别名为Valid和Check, 而Forum类则提供两个属性来返回这个两代理类型, 返回值就是ForumPermission中的静态方法. 那么在需要校验权限的代码中, 只要通过Forum类的两个属性就可以取到对应的校验方法实体.
实现起来有些绕, 但是这样却很好地做到了将Permission实现和Application实现分开. 因为Application对象中返回的校验方法(属性)是声明性的(代理), 假如Permission机制需要作出改变, 那么只要改动PermissionBase中的代理声明和继承自它的[ApplicationName]Permission子类具体实习即可, 而Application的代码则不需要做任何的改动. 把某个动作根据具体实现交由其他类实现, 正是Strategy模式的精髓所在.
其实Strategy模式不光在Validation操作中应用广泛, 甚至ASP.NET本身就是基于Stategy模式的, 当HttpRuntime拿到具体请求的HttpContext时, 它会根据不同的请求(web page || web service)选择不同的HttpHandler, 并将HttpContext作为参数传入. 这样也就实现了runtime和具体响应操作的分离. 从而在出现新的请求类型时, 能够很方便地扩充系统.
最后聊一下权限系统的两个校验方法, Valid主要是通过返回一个bool值来表示用户是否有某种操作的权限, 而Check则是通过抛出异常或者转向页面来进行限制. 详细实现细节就请各位勤奋一点自己看代码了:)