最开始学习的时候,老师带做项目时,是把用户名和可以访问的URL都塞到一个表里。系统启动用户登录时,去遍历这个表找到该用户的所有可访问URL,存到该用户的session里。当访问相关页面时进行权限验证,就查这个用户session里是否有当前URL。当时觉得这样并不好,也没有仔细想。
其实这种做法算是简单安全,毕竟URL直接匹配。如果有缺点的话,可能不好扩展,当项目做大这个逻辑就要改变。
windows里的权限设置是通过角色,可以创建一个角色,给这个角色设置一些权限。当有新用户直接给他一个角色。这其中涉及了角色的思考和用户适合哪个角色,整合的内容稍微有些多。当然也可给用户单独设置功能,直接绕过角色。被访问的“页面”也要记住自己可以被哪些角色访问。用户和访问页面之间有一个,个人认为有些偏绕闹的,桥梁。
假设每一个要进入的页面都有一个门,每一个用户都有一串钥匙。进门的步骤就是用户从钥匙环上找到对应的钥匙,然后尝试开锁,如果钥匙对就可以打开。其中带钥匙是用户的职责,从钥匙环上找到对应门的钥匙属于这个场景才会发生的动作,检验找出的钥匙是否能开锁属于“门”,这个页面,的职责。可以把这些动作分别分配给用户,门前的过滤器,以及门。也就是用户类储存钥匙环,做拦截的过滤器寻找到相关钥匙,页面做验证动作。分属到三个不同的类里完成。
这样的结果可能和最开始那种是一样的。相比来说,最开始那种直接存储URL属于面向过程的,意思是直接考虑这个功能怎么用最简单的方式实现。上一段的方式属于面向对象的,把这一件事思考着分解出合适的动作,匹配到合适的类上。
创建一个user,把它放到session里来代表用户,user有一个储存钥匙环的集合,有一个检查钥匙环的动作。url拦截,doFilter中从session里获取用户,执行它的检查钥匙环动作。这里可以给user多一个长度为3的小数组,这个数组放被查找出来的钥匙。试用场景就像经常访问一扇门,于是在第二次可以很快找到这把钥匙。接着在url的处理类中,需要验证钥匙的匹配,这里考虑给user多一个theKey属性,代表通过filter找到的钥匙,通过对这个钥匙的检验,来最终确认用户可以访问。其中小数组的作用是进入filter首先调用,无果后继续检查钥匙环本体,仍然没找到就无权访问,找到了就把值付给theKey属性。
其中带钥匙的职责归user。检索是否有钥匙并在没权限时退出,属于filter职责。即使找到了钥匙,钥匙最终是否可以打开,属于页面的职责。
这样做的好处是把这个实现过程场景化。不是实现一个功能,是分析出这个场景并分配职责。从机器功能的思考转变成人为做事的思考。如果每一步都这样做,这个项目就很容易铺展。包括后期增加了新功能需要拓展,或者另一个团队来接手项目时对已经存在的功能进行评估。方便项目建设、也容易让项目适应可能进行的成长,显得很有健壮性。在细节架构思路上的思考更多偏向生活中的交流活动,更少直接考虑计算机世界怎么完成功能,留出呼吸的空间理顺整个项目的运作。