当然先手写大概流程:
1.shiro简介
2.集成shiro核心分析
3.无shiro的SpringBoot
4.集成shiro进行用户授权
5.shiro缓存
6.shiro记住密码
7.shiro验证码
第一步:shiro简介:
shiro是开源安全框架,主要功能:认证、授权、加密、回话管理。
shiro三大核心组件:
- Subject当前用户操作
- SecurityManager用于管理所有的Subject
- Realms用于进行权限信息的验证,也是我们需要自己实现的。
先简单理一下,首先shiro先通过核心Filter来实现,就像SpringMvc通过DispachServlet来控制一样。Filter:通过url规则进行过滤和权限效验,我们想要定义一系列Url规则和访问权限来控制。
运行程序将上面走过了解整个规则之后,会进行Realms认证和授权,Realms的Authentication和Authorization。其中Authentication是用来验证用户身份,Authorization是授权访问控制,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等。
第二步:集成Shiro核心分析
1.ShiroFilterFactory,Shiro过滤器工厂类,具体的实现类::ShiroFilterFactoryBean,此实现类是依赖于SecurityManager安全管理器。
2.sercurityManager,shiro的安全管理,主要是身份认证的管理,缓存管理,cookie管理,ShiroFilterFactory主要配置好了Filter就可以了。当然SecurityManager并进行身份认证缓存的实现,我们需要进行对应的编码然后进行注入到安全管理器中。
3.Realm,用于身份信息权限信息的验证。
4.其它的就是缓存管理,记住登录之类的,这些大部分都是需要自己进行简单的实现,然后注入到SecurityManager让Shiro的安全管理器进行管理就好了。
第三步:无shiro的SpringBoot
1.配置依赖:
2.编写前端页面路劲要注意:src/main/resouces/templates
这里还有其他页面可以自己随便写两个就行
3.编写启动类:
4.编写HomeController类
上面都是最简单的小demo,现在来重点:
第四步 集成shiro进行用户授权:
这里要分几点说:
1.pom.xml需要加依赖
2.注入 shiro Factory 和SecuirtyManager
3.身份认证
4.权限控制
1.shrio依赖
2.注入Shiro Factory和SecurityManager;
首先截图不给力截图主要部分创建一个类ShiroConfiguration类中方法如图:
这里要解释一下:
anon:所有url都都可以匿名访问;
authc:需要认证才能进行访问;
user:配置记住我或认证通过可以访问;
ShiroFilterFactoryBean处理拦截问题的时候需要注入:SecurityManager否则报错
3.身份认证这里不得不提数据库,这里会用jpa首先解释一下jpa的标准是你操作的是实体类,数据库由jpa来维护,这个意思就是你写过实体类对应表的关系,数据库你就不用管了,你只需要启动项目jpa就会帮你自动生成数据库表的关系,他参考你的而实体类。
a:加数据库依赖和jpa
b:数据库连接
c:实体类
d:身份认证
a如图:
b如图:
c:是数据库实体类我就要解释一下我的原理:
我们现在要建立用户登录表Userinfo、角色表SysRole、权限表SysPermission
一个用户对应是有多个角色的,一个角色对应不同的权限,当然一个权限也可以对应多个角色
所以 用户vs角色 一对多 角色vs权限 多对多
举例: 一个用户A研究生,A的角色既可以是老师,也可以是学生,
学生权限:吃饭、睡觉,上课。
老师权限:吃饭、睡觉,教书。
这里需要注意这只是其中一种理解方式,你会发现权限会重复吃饭睡觉,那怎么办,我们换一种理解方式
举例: 一个用户B研究生,B的角色既可以是老师,也可以是学生,
学生权限:吃饭、睡觉,上课。
老师特殊权限:教书
这样你会发现你不会重复,我的意思,一个角色就固定权限,但是特殊的角色你就给他特殊的角色权限这样不会重复。
这里写过记得加上get、set方法和toString方法,然后启动程序,你会神奇发现数据库会自动建表。
好啦数据库建成插入数据,记得要一一对应上啊:
INSERT INTO `SysPermission` VALUES ('1', '1', '用户管理', '0', '0/', 'userInfo:view', 'menu', 'userInfo/userList');
INSERT INTO `SysPermission` VALUES ('2', '1', '用户添加', '1', '0/1', 'userInfo:add', 'button', 'userInfo/userAdd');
INSERT INTO `SysRole` VALUES ('1', '1', '管理员', 'admin');
INSERT INTO `SysRole` VALUES ('2', '1', 'VIP会员', 'vip');
INSERT INTO `SysRolePermission` VALUES ('1', '1');
INSERT INTO `SysRolePermission` VALUES ('1', '2');
INSERT INTO `SysUserRole` VALUES ('1', '1');
INSERT INTO `SysUserRole` VALUES ('1', '2');
INSERT INTO `UserInfo` VALUES ('1', '管理员', 'admin', 'd3c59d25033dbf980d29554025c23a75', '8d78869f470951332959580424d4bf4f', '0');
上面如果都准备完成了,就可以进入逻辑层了。
UserInfoRepository类用户类的持久化
这里还要编写调用这个方法的类,这里用mvc模式,一个接口一个实现类:
其实上面所有的步骤都是为这一步打基础,shiro的认证是交给Realm执行了。所以我们需要自己重新实现一个Realm,此Realm必须继承AuthorizingRealm。
这里不好截图我就先解释一下必须继承AuthorizingRealm原因:
因为在AuthorizingRealm中有两个方法:
doGetAuthenticationInfo();
doGetAuthorizationInfo();
其中doGetAuthenticationInfo主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。(如图)
至于doGetAuthorizationInfo()是权限控制,当访问到页面的时候,使用了相应的注解或者shiro标签才会执行此方法否则不会执行,所以如果只是简单的身份认证没有权限的控制的话,那么这个方法可以不进行实现,直接返回null即可。
在这个方法中主要是使用类:SimpleAuthorizationInfo
进行角色的添加和权限的添加。
authorizationInfo.addRole(role.getRole());
authorizationInfo.addStringPermission(p.getPermission());
当然也可以添加集合:
authorizationInfo.setRoles(roles);
authorizationInfo.setStringPermissions(stringPermissions);
如图:
这里要加点东西,因为手写的Realm,默认是读取不到的,所以我们要在ShiroConfiguration过滤器那边,Realm注入到SecurityManager中。
身份认证基本完成了还要在homeController哪里加上login post处理
这里登录肯定还会报错因为我们密码是用密文方式加密还要编写一个方法类ShiroConfiguration:
4.权限控制这是最让人头疼的
然后运行登录进行访问:http://127.0.0.1:8080/userInfo/userAdd
并没有执行doGetAuthorizationInfo()打印信息,所以我们会发现我们的身份认证是好使了,但是权限控制好像没有什么作用哦。
我们少了几部分代码,
第一就是开启shiro aop注解支持,这个只需要在com.kfit.config.shiro.ShiroConfiguration加入如下方法进行开启即可:
这时候在访问http://127.0.0.1:8080/userInfo/userAdd会看到控制台打印信息:
权限配置-->MyShiroRealm.doGetAuthorizationInfo()
如果访问:http://127.0.0.1:8080/userInfo/userDel会看到
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat May 21 22:17:55 CST 2016
There was an unexpected error (type=Internal Server Error, status=500).
Subject does not have permission [userInfo:del]
当然我们需要在UserInfoController方法中加入:
在上面的错误信息中Subject does not have permission可以看出此用户没有这个权限。好了,至此Shiro的权限控制到此先告一段落。在这里我先抛出一个问题:我们不断的访问http://127.0.0.1:8080/userInfo/userAdd你会看到
留下Demo地址:
http://pan.baidu.com/s/1mhTr8Ju
####指导qq:179061434