权限管理「基于角色的访问控制(RBAC)」
很多时候,需要对一些事物进行控制,如一个房间,为了不让人随便进,通常会装一把锁,如果要想进入,你必须得有一把钥匙,且还得和这个锁匹配才行。
基于此做一个抽象,其实包含三方面内容:
1)一个是被控制的事物,通常就算资源。
2)一个是想访问这些资源的人所必须拥有的东西,通常就算凭证。
3)还有一个就是进行凭证和资源的匹配。
Web应用中的资源
网络时代绝大多数都是web应用。web应用的一大特点就是Client和Server。客户端发起一个请求,服务器就给出一个响应。
对客户端的要求只有一个,那就是要知道请求对应的URL。客户端请求不同的URL就可以得到不同的内容,或者反过来说,客户端为了得到不同的内容只要请求不同的URL即可。
这些内容可以认为是服务器开放给客户端的资源,所以站在客户端的角度,服务器上的资源就是由许多URL组成的,因为客户端只能通过URL的方式和服务器打交道。
URL可以说是一个底层本质的东西,它的上面会有很多不同的展现形式:
菜单可以对应URL
页面可以对应URL
按钮可以对应URL
Ajax可以对应URL
服务API可以对应URL
文件下载可以对应URL
静态文件css、js、images可以对应URL
这些就是通常我们见到的资源,它们就是要被控制访问的事物。
把凭证授给用户
凭证这个东西的作用,大家都很熟悉,就是可以用来证明一个事物的合法性。比如一个身份证可以证明你是一个合法公民。一张车票可以证明你是一个合法乘客。
但是对凭证的存在形式,其实并没有什么硬性规定,因为随着时间的推移,它是会变的,也就是说具有阶段性。
就拿锁来说,它的凭证以前是一把钥匙,后来变成一串数字密码,再后来变成一个指纹,现在又变成一张人脸或一个声纹,再往未来发展,可能就是一种意念了。
web应用中的资源就是URL,我们可以把这个URL直接作为凭证授予用户,只需把这些授予关系存储起来即可,说白了就是,哪个用户可以访问哪些URL。
或者也可以把这些URL进行等价变形,把变形后的产物授予用户,总之,只要能建立起合理的映射关系就行了。
角色出现的必然性
假如有一个新闻系统,为了让某人能顺利的发新闻,需要由技术人员授予她一大堆的URL。这样一个“简单”的事情中,就存在两个潜在的弊端。
一个是必须由技术人员来做,因为非技术人员可能连URL这个词都不知道是什么。一个是一大堆的URL,太多了,操作麻烦,还可能漏掉某个。
究竟由谁发新闻,这是业务和管理上的事情,不应该由技术来做,他们不做的原因是因为门槛太高,所以技术应该想办法来降低工作的门槛。
可能领导觉得现在的新闻发布人员工作很认真,于是让她去审核新闻了,又来了一个新的新闻发布人员。这下又要“折腾”技术人员了。
技术需要先把她的发布新闻URL去掉,授给她审核新闻的URL,然后再把发布新闻的URL授给新来的人员。可能过两天又来了一个新闻发布人员。
这可简直要了技术人员的“命”了,所以技术应该想办法来降低工作的繁琐性,绝对是利人又利己。
在计算机里,解决此类问题的一个“标准指导方针”就是,抽象和封装。抽象出一层来,把复杂的东西封装起来。
就是让不该看的人看不到他不该看的东西,只让他看到他该看到的东西。就像同一个事物在不同人眼里是不一样的。
一栋大楼,在设计人员眼里就是一堆图纸,在工程人员眼里就是一堆结构和承重计算的公式,在建筑工人眼里就是一堆钢筋和混凝土,在装修人员眼里就是毛坯房,在业主眼里就是他自己未来的家。
最终角色这个东西就是被抽象出来的一层,它起到过渡的作用,从这一层向下是技术人员负责的,从这一层向上是业务管理人员负责的。
技术人员预定义好一些角色,比如新闻发布员、新闻审核员,然后把和发布相关的所有URL授予发布员这个角色,把和审核相关的所有URL授予审核员这个角色。
剩下的工作就交给业务管理人员来做,他们把角色授予某个人,只需一步即可,也不涉及什么技术知识。这真是各管各的,两全其美。
其实这个角色就是上面提到的一堆URL的等价变形,最终起到的也是一个传递映射关系的桥梁作用。
凭证和资源的匹配方式
在持有凭证去访问资源的时候需要进行凭证和资源的匹配。就像进考场要看准考证、上车前要验票一样。
凭证的存在形式不同,匹配的方式也不同,如果是钥匙,需要机械匹配。如果是密码,需要相等性匹配。
如果是指纹、图像、声纹,需要的是概率性匹配,因为这些东西貌似无法相等,只有一个匹配度。
对于web应用的URL,只有用户访问时才需要匹配,我们就在请求必经的路上设置一到多道关卡进行拦截,常用的就是过滤器和拦截器。
在被拦截以后,从请求中解析出本次访问的URL,从当前登陆用户信息中拿到具有的角色和能访问的URL,然后按自己设定的一套逻辑去匹配。
如果匹配成功就放行,会自动进行后续处理。匹配不成功就禁止通行,告诉他不能通行的原因,结束本次访问。
基于角色的访问控制
其实上面讲的就是基于角色的访问控制的原理。原理很简单,如果没有特殊要求的话,实现也不难。
就是经典的五张表:
1)权限表,也称资源表,记录所有的资源URL。
2)角色表,记录所有的角色。
3)角色权限表,记录每个角色都能访问哪些权限。
4)用户表,记录所有用户。
5)用户角色表,记录每个用户被授予的角色。
按实际需求决定的部分:
1)一个用户是只能有一个角色,还是可以有多个,这个依托用户角色表即可实现。
2)角色之间是否可以继承,是单继承还是多继承,这个需要一个单独的角色继承表来存储。
两个特殊的事物:
1)一个是没有任何限制的公共资源,如js、css、images等,可以设置一个白名单,把它们放入其中,这些URL相当于“免检”。
2)一个特殊的用户,如超级管理员,这个需要在用户表进行标识,遇到它后直接放行,因为它也是“免检”。
是否选择现成的框架
常用的现成的框架就是Spring Security和Apache Shiro。它们属于上手不难,想用好却不简单的那种。
我觉得可以按以下情况来选择:
1)有专门团队或人员维护的,可以选择从零研发或基于框架的深度扩展。
2)没有专人负责,也不想麻烦的,建议不要用框架,应该自己写代码简单实现。
3)不怕麻烦的,爱研究的,可以选择框架,掌握使用方式,明白运行原理,看看底层源码。
总之,一定要做到可控,特别是自身或团队在条件不允许的情况下,千万别去捅马蜂窝。
两年呕心沥血的文章:「面试题」「基础」「进阶」这里全都有!
300多篇原创技术文章加入交流群学习海量视频资源精美脑图面试题长按扫码可关注获取
在看和分享对我非常重要!
评论