1.原文地址
http://www.lgygg.wang/lgyblog/2019/09/04/j2eeshiro%e6%8e%88%e6%9d%83%e5%92%8c%e8%ae%a4%e8%af%81%e6%a1%86%e6%9e%b6/
2.落笔缘由
登录的认证和授权操作几乎是每个项目都必备的功能,所有在网上找了相关的资料,发现 shiro框架符合我的需求,所有到慕课网上找到了学习视频,本文就是根据该视频做下的学习笔记。
3.Shiro认证
点击Open Implemention
可以看到下面的图,打开DelegatingSubject类,
可以看到login方法里调用了securityManager的login方法,也就是shiro认证过程的第三步SecurityManager认证
然后调用Authenticator认证, 也就是shiro认证过程的第四步Authenticator认证
最后调用Realm验证, 也就是shiro认证过程的第五步Realm验证
4.Shiro授权
Shiro授权即判断该用户是否是某种角色,如果拥有某种角色,那么它就拥有这个角色的权限。如下图,当前一个名为“LGY”的用户,拥有admin的角色,然后通过下面的checkRole方法就可以检查这个用户是否具有admin角色权限。
5.Realm
1)IniRealm
checkPermission方法检查用户是否有删除权限
2)JDBCRealm
3)自定义Realm
测试
6.Shiro加密
1)对加密的密码进行认证
2)在自定义的Realm加盐
7.Shiro整合spring
1)在web.xml中创建创建shiro 安全过滤器
然后在web.xml配置spring的配置文件
并创建springmvc.xml配置文件
2)配置加密的管理器對象
这里是在spring.xml文件里配置的,其实这个spring.xml文件就是以前项目中的applicationContext.xml文件,
3)配置Realm对象
4)配置securityManager安全管理器
5)配置shiro的bean
这里配置web.xml中shiro的filter对应的bean
8.Shiro集成spring,并从数据库获取数据
上一个例子也是Shiro集成spring,但是它验证的数据并不是从数据库获取的,而是我创建的用户数据,如下图,
在实际项目中,数据必定是从数据库中获取的,所以这个例子是关于如何从数据库拿数据出来验证的
首先在pom.xml文件里添加需要用到的数据库包,如下图,在SSM架构的项目中,会使用MyBatis来连接数据库,这里为了简便,我们用spring-jdbc包来连接数据库
编写连接数据库的文件spring-dao.xml
在spring.xml文件中,引入这个spring-dao.xml文件
编写查询语句
编写controller,最后用户的认证和权限是在controller里判断的
9.通过注解配置权限
导入aspectjweaver
开启基于注解的事务,通过这个设置,允许开发人员通过注解的方式授权
下面是到controller里使用角色或者权限注解,限制被@RequiresRoles和@RequiresPermissions修饰的方法,只有当前用户拥有角色和权限才可以被调用
结果如下
在这个过程中,碰到@RequiresPermissions 和@RequiresRoles 注解无效的现象,原因是刚开始的时候,在web.xml中我使用的是如下的dispatcherServlet分发配置文件是dispatcherServlet-servlet.xml
而不是spring-mvc.xml ,然后我将web.xml的做了如下配置
下图是spring-mvc.xml的配置内容
这就导致了 spring-mvc.xml里面的配置内容无法被调用,导致无效,但是即使你把spring-mvc.xml搬到spring.xml中也是没有用的,因为spring-mvc.xml里的配置内容必须要是web.xml里指定的dispatcherServlet指定的文件里配置,所以如果web.xml里设置的dispatcherServlet是dispatcherServlet-servlet.xml,那么把spring-mvc.xml里面的配置的内容放到dispatcherServlet-servlet.xml也是能正常使用注解的。
10.Shiro过滤器
首先在controller里写几个测试服务,这几个方法都不要有权限和角色注解,避免影响测试结果
然后到spring.xml文件里写过滤
这里写过滤和给方法上用注解来过滤产生的效果是有一点不一样的,如果用户没有权限或者没有角色,用户都无法访问这个服务,但是如果给方法上用注解的方法来实现的话,是会在后台打印出异常的,用户在浏览器上也可以看大异常,但是如果是如上的方法过滤,就只会提示404或者403
这是因为我配置了
11.Shiro会话管理
首先导入Redis
创建JedisUtil(用于操作Redis数据库,对数据库进行增删改查操作),
并创建RedisSessionDao类,这个类集成了Shiro的AbstractSessionDAO方法,主要是定义Shrio操作Session的一些接口
然后再spring.xml文件中注册,指定使用这个sessionManager来管理Session
然后要配置spring-redis.xml文件
并在spring.xml中引入这个配置文件
这里是用Redis数据库来实现session的共享,本来以为Redis只是一个架构,只需要添加依赖就好,后面报错redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool] with root cause,去网上搜索,才忽然想起这是一个数据库,虽然是免安装的,但是还是需要下载下来运行,具体安装步骤可以看:https://www.runoob.com/redis/redis-install.html
根据网上的教程,启动了Redis服务器,
项目终于可以运行了
然后我想安装一个Redis的可视化界面操作工具Redis Desktop Manager,但是发现Redis Desktop Manager作者在 0.9.4 版本之后选择对所有的安装包收费,不再提供安装包下载,但是源码依旧公开,而0.9.3成为最后一版不收费的版本。
登录成功后,会发现RedisSessionDao的方法被多次调用,这样会导致多次重复访问Redis数据库
为了避免这种情况,需要我们自定义SessionManager,下图就是自定义的SessionManager
然后还需要到spring.xml中指定这个SessionManager,如下图,改为我们自定义的SessionManger即可
如下图,方法就只调用了一次
12.Shiro缓存
主要用于缓存角色数据和权限数据。
先创建自定义的缓存管理器RedisCacheManager已经它的缓存处理类RedisCache,如下图
然后再spring.xml文件中指定这个缓存管理器即可
13.自动登录
首先,要到spring.xml中做配置,如下图,先配置一个SimpleCookie,然后再配置一个CookieRememberMeManager,最后将这个CookieRememberMeManager再securityManager里配置
给User类新增一个rememberMe属性
然后在登录界面添加一个记住我的CheckBox
最后,在控制器里加入下图红框中的代码
这里需要说明的是,自动登录的效果并不是说当我第一次登录的时候选中了记住我,下次打开登录界面,不需要用户自动登录,这个网页就会自动登录进去了。而是如下的效果,第一次登录成功后
登录成功后,跳到如下界面
然后我们关了当前界面,访问 http://localhost:8080/shiro-web/testRole 这个页码,这个界面之前是需要登录成功后才能能访问。但是现在还是可以访问。但是,如果你访问登录界面,显示的还是登录界面,刚开始没有转过来,认为shiro的自动登录并不是我前面提到的自动登录,但其实就是这样的,因为我们之前需要登录才能调到的服务现在也能调到了,所以用户访问登录界面,不需要用户自动登录,这个网页就会自动登录进去到主页的效果的逻辑是需要我们自己写的。
14.获取源码
其实视频中的教学很详细,大家完全可以根据视频一步一步的把完整的代码整理出来,对于不想花时间去整理的同学,我个人整理了一份,里面有个人的一些理解,需要的同学可有通过扫描二位码支付20元并附上邮箱和关键字“1-0002”
或者通过以下淘宝地址链接直接购买,支付的时候请附上自己的邮箱
https://item.taobao.com/item.htm?spm=a2126o.11854294.0.0.7e764831kJaGsW&id=602257658164