EverydayOneCat
睡到模糊.jpg
权限控制
1.认证和授权
1.1概念
问题1:在生产环境下我们如果不登录后台系统就可以完成这些功能操作吗?
答案显然是否定的,要操作这些功能必须首先登录到系统才可以。
问题2:是不是所有用户,只要登录成功就都可以操作所有功能呢?
答案是否定的,并不是所有的用户都可以操作这些功能。不同的用户可能拥有不同的权限,这就需要进行授权了。
认证:系统提供的用于识别用户身份的功能,通常提供用户名和密码进行登录其实就是在进行认证,认证的目的是让系统知道你是谁。
授权:用户认证成功后,需要为用户授权,其实就是指定当前用户可以操作哪些功能。
1.2权限模块数据模型
要实现最终的权限控制,需要有一套表结构支撑:
用户表t_user、权限表t_permission、角色表t_role、菜单表t_menu、用户角色关系表t_user_role、角色权限关系表t_role_permission、角色菜单关系表t_role_menu。主要由4张主体表和3张关联表构成。
在这7张表中,角色表起到了至关重要的作用,其处于核心位置,因为用户、权限、菜单都和角色是多对多关系。
接下来我们可以分析一下在认证和授权过程中分别会使用到哪些表:
认证过程:只需要用户表就可以了,在用户登录时可以查询用户表t_user进行校验,判断用户输入的用户名和密码是否正确。
授权过程:用户必须完成认证之后才可以进行授权,首先可以根据用户查询其角色,再根据角色查询对应的菜单,这样就确定了用户能够看到哪些菜单。然后再根据用户的角色查询对应的权限,这样就确定了用户拥有哪些权限。所以授权过程会用到上面7张表。
2.Spring Security
之前在品优购中我们已经介绍过了Spring Security,在品优购中,我们主要是对其的认证功能进行了具体介绍。博文地址
其实Spring Security的授权功能是最常用的,认证功能我们之前的Cas完全可以取代Spring Security自带的。
这里我们主要对Spring Security的授权功能做具体介绍。常用的权限框架除了Spring Security,还有Apache的shiro框架。
2.1入门Demo
配置web.xml
1 |
|
在spring-security.xml中主要配置Spring Security的拦截规则和认证管理器。
1 |
|
创建类继承UserDetailsService并作为容器放入Spring,Spring Security会自动识别并实现里面定义的方法。
通过实现UserDetailsService,给框架提供一个方法。该方法框架会传递用户名过来,获取一个UserDetail对象。通过此对象,框架可以获取用户名和密码,自行进行正确与否的校验。完成登录操作。
1 | public class SpringSecurityUserService2 implements UserDetailsService { |
2.2密码加密
这里密码着重说一下,Spring Security中默认密码是加密的,如果存储的用户密码是明文(即没有加密),我们需要在前面加上{noop}字符串作为标识,如
<security:user name="admin" password="{noop}1234" authorities="ROLE_ADMIN"/>
常见的密码加密分为两类:对称加密和非对称加密。
对称加密就是使用算法,把原文A计算为密文B。同时,使用算法的逆运算,还可以把密文B还原为原文A。一般用于信息传输加密。对称加密存在通过一种方法把所有这种方式加密的所有密文都破解。
非对称加密:
一般是一些摘要算法,算法不可逆。即使知道算法的全部内容,也无法还原原文。
原文A计算为密文B,密文B不包含原文的所有信息,仅仅是使用原文计算出来的一个单独的字符串。无法还原。
非对称加密虽然不可逆,但是由于如果被加密的对象不变,加密内容不变。一般可以通过暴力破解(一个个的尝试)来获取值。这时候我们还有一种方法使得密码更安全:加盐。
加盐就是将原本被加密的对象放入几个字符串,‘盐’往往也存储在数据库,但是就算被黑了得到了‘盐’,人家也不知道你这个盐加在哪里,以何种方式加的,所以相对来说安全很多。
常见的密码加密方式有:
3DES、AES、DES:使用对称加密算法,可以通过解密来还原出原始密码
MD5、SHA1:使用单向HASH算法,无法通过计算还原出原始密码,但是可以建立彩虹表进行查表破解
bcrypt:将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题
2.3注解方式权限控制
Spring Security除了可以在配置文件中配置权限校验规则,还可以使用注解方式控制类中方法的调用。例如Controller中的某个方法要求必须具有某个权限才可以访问,此时就可以使用Spring Security框架提供的注解方式进行控制。
在一般的场景中,我们一般注解来针对方法进行权限控制
spring-security.xml文件中开启权限注解支持
1 | <!‐‐开启注解方式权限控制‐‐> |
创建Controller类并在Controller的方法上加入注解进行权限控制
1 |
|
3.项目中应用Spring Security
3.1环境配置
web.xml文件中配置用于整合Spring Security框架的过滤器DelegatingFilterProxy
1 | <!‐‐委派过滤器,用于整合其他框架‐‐> |
提供spring-security.xml配置文件
1 |
|
这样我们想进入page下面的页面时,必须先进入login.html执行登陆操作,登陆成功才能进入。
3.2实现认证和授权
按照Spring Security框架要求提供SpringSecurityUserService,放入Spring容器中,并且实现UserDetailsService接口
1 |
|
Service实现根据用户名查询数据库获取用户信息和关联的角色信息,同时需要查询角色关联的权限信息
1 | /** |
这里Dao需要用到多表查询,之前的博文介绍过方法,这里不过多赘述,提供关键性sql语句
1 | select r.* |
3.3测试授权
在Controller的方法上加入权限控制注解,此处以CheckItemController的Delete方法为例
1 | //删除 |
我们通过sql语句查询目前两个角色权限的区别
1 | select p.* from t_permission p,t_role_permission rp WHERE |
发现xiaoming这个用户并没有删除检查项这个权限,我们登录xiaoming测试,发现的确删不掉。服务器返回403Forbideen错误。
修改页面,没有权限时提示信息设置,此处以checkitem.html中的handleDelete方法为例
1 | //权限不足提示 |
修改删除方法,在catch(服务执行失败执行)中执行刚刚定义的方法
1 | // 删除 |
结语
菩提本无树,明镜亦非台。
佛性常清净,何处有尘埃!
心是菩提树,身为明镜台。
明镜本清净,何处染尘埃!
菩提本无树,明镜亦非台。
本来无一物,何处惹尘埃!
菩提只向心觅,何劳向外求玄?
听说依此修行,西方只在目前!