1.通常的权限管理需求:
可见性----页面元素的显示与否或可用与否
可访问性----后台URL是否可以访问
权限管理的设计需要结合两个方面,可见即可访问,不可见亦不可访问。
对于该设计的实现而言,可见性和可访问性是两个维度的设计。
2.可见性设计
首先明确一个词汇:资源,我把页面需要权限管控的标签或代码块称之为“资源”,一个资源可以是一个按钮、一个DIV、一个Table、一个字符串......
资源被授给角色,角色被授给用户......
给每一个资源定义一个唯一的Key值,这个Key值唯一标识了这个资源的存在,也是权限可见性管控的关键。
这个Key值建议使用会意的字符串,而不是抽象的数字,比如某个按钮“Topmenu_SubMenu_List_AddButton”,力求在看到Key值时即可定位这个资源的位置。
书写自写权限标签将Key值作为属性值嵌入,用该权限标签套在需要包装的资源外面。
用户登录系统后会加载改用户对应的角色和资源保存到Session里。
在用户请求的每一个页面被服务端初始化时会执行页面的权限标签,标签的处理逻辑是如果Session中能找到这个Key的资源,则将这个标签去掉并显示被标签包含的内容,如果Session中没有这个Key值得资源,则将这个标签和标签里的内容全部去掉。通过这个逻辑即达成了可见性的管控。
有人喜欢用URL来作为这个Key值,这种做法不能覆盖所有需求,因为有些资源是没有URL的,并且URL不够会意,不能够显示出资源的层级关系,通常的层级是父菜单-->子菜单-->功能集合-->子功能集合-->其他。
3. 可访问性操作
对于某些Key值需要匹配对应的URL,比如可提交的按钮必然有一个(或一组)确定的URL,那么这个按钮的Key值就应该对应到这些URL,它们的对应关系作为一条资源的记录保存在数据库或属性文件中。
也就是说资源不仅仅指一个Key值,也包含了Key值对应的URL,只是URL是可以为空。
用户登录系统后会加载用户对应的角色和资源和可访问的URL保存到Session里。
在用户请求每一个URL的时候,Web服务器会检查Session中是否有记录与当前提交的URL匹配,如果有则继续执行,如果没有则直接响应错误页面。通常这种操作应该放在拦截器中实现。
可以想象,没有访问URL权限的情况肯定是用户直接在地址栏直接敲入的URL,而并非从页面点击提交上来的,因为如果这个URL用户没有权限访问,那么对应的资源也是没有权限的,从而知道用户在页面上应该是看不到这个按钮或链接的。
4. 结论
通过资源的定义、自写标签的解析、拦截器的拦截达成了可见性和可访问性一致的权限设计初衷。
5. 旁白
感谢我老婆给我很多好的建议,作为Java程序员我从ASP.NET的框架设计学习到了很多。后续还有更详细的论述和代码下载。