基于操作+角色的授权方案(具体实现篇)

基于操作+角色的授权方案 思路篇

 

接上文,上一篇随笔说了基于操作+角色授权方案的设计思路,本随笔谈谈如何实现,可以方便高效的使用此方案。

在这套授权方案中角色是用户可配置的,而操作是死的,我们在程序中实现了什么功能就有什么样的操作,所以我们充分利用这一点,为了使用方便我们将操作作为PageBase(项目中统一的Page基类)的Attribute来定义,然后在PageBase对应页面执行PreLoad事件时读取此页面上定义的Attribute属性中的操作,然后读取当前用户可执行的操作,对比得到用户是否有访问该页面的权限。
ActionsAttribute的实现很简单,就是定义了一个只读的string数组来存放页面功能中的操作。其实现如下:

[global::System.AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public sealed class ActionsAttribute : Attribute
{
    
public readonly string[] PageActions;


    
public ActionsAttribute(params string[] actions)
    {
        PageActions 
= actions;
    }
}

我们需要在PageBase类中实现对ActionsAttribute(即当前页实现操作)的读取和对权限的判断,关键代码如下

PageBase中的实现
大家都知道读取Attribute是通过反射来做的,其性能会有问题,所以我们生命了一个静态的成员变量_pageActionsDict来保存解析出来的Attribute和Page类型的对应字典,这样所有页面的Attribute都仅需要读取一遍,对性能几乎没有影响。
在上面的方法中我们使用了LoginUser.CanDoAction方法,其中LoginUser是PageBase的一个属性,表示当前登录的用户,在User类中有对当前用户权限的判断。其相关代码如下:
User类中判断权限部分

这两个方法没有具体实现,不过有了设计思路实现是很简单的。

我们在具体使用中,就是直接给具体的Page类加上Attribute了,如下示例代码:

    [Actions(ActionsConst.EnterAdmin)]
    
public partial class Default : PageBase
    {
        
protected void Page_Load(object sender, EventArgs e)
        {
            
        }
    }

 

其中ActionsConst是系统中所有操作的常量定义类。

全文完。


我的微博地址是:http://weibo.com/yukaizhao 我会把一些技术心得碎片写到微博中,欢迎关注。
posted @ 2008-11-21 09:18 玉开 阅读(3163) 评论(23) 编辑 收藏

 回复 引用 查看   
#1楼[楼主]2008-11-21 09:26 | 玉开      
大家有不同的思路或者疑问请提出来呀。
 回复 引用 查看   
#2楼2008-11-21 09:28 | 张明海      
很早.不错 呵呵
 回复 引用 查看   
#3楼2008-11-21 09:30 | 菌哥      
能不能放一个完整的demo研究研究
 回复 引用 查看   
#4楼[楼主]2008-11-21 09:31 | 玉开      
@张明海
谢谢支持呀
@菌哥
思路和多半的实现都有了,具体demo就不放了吧,大家讨论思路实现我觉得现有的东西已经够了。

 回复 引用 查看   
#5楼2008-11-21 09:41 | 上海本帮菜      
为啥看不懂捏????愁人
 回复 引用 查看   
#6楼[楼主]2008-11-21 09:45 | 玉开      
--引用--------------------------------------------------
上海本帮菜: 为啥看不懂捏????愁人
--------------------------------------------------------
哪儿看不懂?

 回复 引用 查看   
#7楼2008-11-21 09:50 | winzheng      
呵呵,思路基本一致,表达方法不同
 回复 引用 查看   
#8楼2008-11-21 09:52 | 幸运草      
还是只能控制页面级别的权限,页面内的按钮,输入框,等部分信息怎么控制 呢
 回复 引用 查看   
#9楼[楼主]2008-11-21 09:59 | 玉开      
@幸运草
可以调用LoginUser.CanDoAction方法判断权限,需要调用一行代码

 回复 引用 查看   
#10楼2008-11-21 10:08 | 幸运草      
--引用--------------------------------------------------
玉开: @幸运草
可以调用LoginUser.CanDoAction方法判断权限,需要调用一行代码
--------------------------------------------------------
调用这个代码是可以完成,但又背离了你的低耦合的设计思路

 回复 引用 查看   
#11楼[楼主]2008-11-21 10:13 | 玉开      
@幸运草
其实也没有背离,到具体资源的时候,还是必须调用方法判断的。

 回复 引用   
#12楼2008-11-21 10:19 | fdsa[未注册用户]
思路挺好的,学习了。
 回复 引用   
#13楼2008-11-21 10:25 | fdsa[未注册用户]
@幸运草

--引用--------------------------------------------------
幸运草: 还是只能控制页面级别的权限,页面内的按钮,输入框,等部分信息怎么控制 呢
--------------------------------------------------------

对控件控制是没必要的,可以对控件实现的功能来控制。也就是在方法上面加特性。

 回复 引用 查看   
#14楼[楼主]2008-11-21 10:46 | 玉开      
@fdsa
我也觉得没有必要对控件进行类似page的控制

 回复 引用 查看   
#15楼2008-11-21 11:32 | kiler      
侵入性太强,不如使用使用httpmoudle+在页面方法上加attribute实现。
 回复 引用 查看   
#16楼[楼主]2008-11-21 11:41 | 玉开      
@kiler
“侵入性太强”有什么问题吗?
因为Attribute中定义的操作,正式页面上实现的功能,所以不存在侵入性太强的问题。
请具体说下你认为“侵入性”造成的问题!谢谢

 回复 引用 查看   
#17楼2008-11-21 12:02 | kiler      
@玉开
要用你这个东西就必须继承你的PageBase类,这就是倾入性啊,人家一个做好的系统用你的东西,意味所有代码都要改。权限检测的代码完全可以放到httpmoudle里面的,这样对现有代码不会有伤害。

关于Attribute使用方式,也可以采用
public partial class Default : PageBase
{
[Actions(ActionsConst.EnterAdmin)]
protected void Page_Load(object sender, EventArgs e)
{

}
}
这样的方式,对页面具体方法设置权限
这样就可以解决上面有人提到的如页面内数据操作的权限,如添加数据,更新数据,因为这些操作最终是要通过页面方法来调用的。

 回复 引用 查看   
#18楼[楼主]2008-11-21 12:20 | 玉开      
@kiler
如果把权限部分当做应用的核心模块用PageBase就没有问题;如果是当做插件就用HttpModule实现,谢谢你的思路。

 回复 引用 查看   
#19楼2008-11-21 12:26 | montaque      
要用你这个东西就必须继承你的PageBase类,这就是倾入性啊,人家一个做好的系统用你的东西,意味所有代码都要改。权限检测的代码完全可以放到httpmoudle里面的,这样对现有代码不会有伤害。

没有必要该代码, 一个web.config就搞定了
<system.web>
<!-- ... -->
<pages pageBaseType="YourBasePageExtensionType" />
<!-- ... -->
</system.web>

 回复 引用 查看   
#20楼[楼主]2008-11-21 12:43 | 玉开      
@montaque
完全放在HttpModule里面,可能会导致HttpModule很复杂,比如涉及到对资源访问的授权。

我赞同你的解耦思想。

--引用--------------------------------------------------
玉开: @montaque

完全放在HttpModule里面,可能会导致HttpModule很复杂,比如涉及到对资源访问的授权。



<b>我赞同你的解耦思想。</b>
--------------------------------------------------------
实际上在MS的WCSF【P&P】中,就是通过HttpModule来实现的,楼主可以研究下源代码

 回复 引用 查看   
#22楼2008-11-22 15:54 | kiler      
@montaque

解决不了根本问题,人家的代码也写了Pagebase,那就没法用了。

 回复 引用 查看   
#23楼[楼主]2008-11-24 08:48 | 玉开      
放在HttpModule中比放在PageBase中更满足软件开闭原则。
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1338139 zh5wA13VzjM=