文档章节

Apache Shiro权限控制实战,权限控制SpringMVC + Mybatis + Shiro

8446666
 8446666
发布于 2016/06/29 14:46
字数 2765
阅读 10314
收藏 54

Demo已经部署到线上,地址是http://shiro.itboy.net
管理员帐号:admin,密码:sojson.com 如果密码错误,请用sojson。
PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快,有问题加群解决。

Shiro Demo 源码下载

Shiro Demo 非Maven项目依赖包下载:点我下载

Shiro Demo 源码下载下载:点我(云端下载)

Github下载:https://github.com/baichengzhou/SpringMVC-Mybatis-shiro

Shiro Demo环境准备

开发工具:EclipseMyEclipseIdea等等。

依赖第三方:Mysql 5.0以上、Redis

需要的配置:jdbc.properties中配置Mysql的信息、spring-cache.xml配置Redis 配置,如果是默认配置,就不用换,Redis Windows安装:http://www.sojson.com/blog/110

注意:请不要有端口8080,设置Tomcat端口为80,然后访问不要带项目路径访问。就好像生产环节一样:http://shiro.itboy.net 。

Shiro 简介

Apache Shiro Java  的一个安全框架。我们经常看到它被拿来和 Spring  Security  来对比。大部分人认为 Shiro  Security  要简单。我的观点赞成一半一半吧。

首先 Shiro  确实和 Security  是同类型的框架,主要用来做安全,也就是我们俗称的权限校验(控制)。居多人对 Shrio  的定义为好入门。

我选型为 Shiro  ,主要的原因扩展太easy了,而且我要的功能它都有。

本教程环境。

本教程Jar包管理是 Maven  ,所以如果是 Maven  项目下载Demo后可以直接使用,如果是普通的Java Web项目,那么请在下面下载所有依赖包。

本教程开发工具是Myecilpse8.5

本教程编码格式为UTF-8

本教程JDK为1.7

本教程Spring版本为4.2.5

前端页面采用Bootstarp 3.2

本教程包含的内容。

  1. SSM(SpringMVC + Spring + Mybatis)框架的增删改查(含分页),所以如果框架小白也是可以看看的。
  2. View层主要是Freemarker,但是为了考虑到好多人还使用的是JSP,也有一个页面是用JSP实现的,并且框架支持FreemarkerJSPView展示(优先找Freemarker)。
  3. Shiro + Redis 的集成,也提供Ehcache的依赖Jar。
  4. Shiro 初始权限动态加载。
  5. Shiro 自定义权限校验Filter定义,及功能实现。
  6. Shiro Ajax请求权限不满足,拦截后解决方案。
  7. Shiro Freemarker标签使用。
  8. Shiro JSP标签使用。
  9. Shiro 登录后跳转到最后一个访问的页面。
  10. 用户禁止登录Demo
  11. 在线显示,在线用户管理(踢出登录)。
  12. 登录注册密码加密传输Demo(详细请见下面讲解)。
  13. 密码修改。
  14. 用户个人中心。
  15. 权限的增删改查。
  16. 角色的增删改查。
  17. 权限->角色->用户之间的关系维护。
  18. 管理员权限的自动添加(当有一个权限创建,自动添加到管理员角色下,保证管理员是最大权限)。
  19. Spring定时任务数据化数据。
  20. 集成多种验证码(包括动态的gif验证码哦)。
  21. 后续会陆陆续续升级... ...

一、SSM(SpringMVC + Spring + Mybatis)框架的增删改查(含分页)

本教程是SSM(SpringMVC + Spring + Mybatis + Freemarker + JSP) + Shiro + Redis 做的整体Demo,其他框架需要自己自行解决,所以不做其他框架的讲解,其实是大同小异。

Controller ==> Service(事务控制层) ==> Dao ==> SqlMapper ==> Mysql

二、View层 Freemarker,JSP

通用View层配置在spring-mvc.xml中的以【通用试图解析器】注释标注的区间配置。

三、Shiro + Redis 的集成,也提供Ehcache的依赖Jar。

Redis 缓存配置主要在spring-cache.xml中。对应的所有Cache 相关 Java  代码在package:com.sojson.core.shiro.cache

四、Shiro 初始权限动态加载。

我们一般是这么加载的。在spring-shiro.xml中配置

 

 
  1. <property name="filterChainDefinitions" >
  2. <value>
  3. /** = anon
  4. /page/login.jsp = anon
  5. /page/register/* = anon
  6. /page/index.jsp = authc
  7. /page/addItem* = authc,roles[数据管理员]
  8. /page/file* = authc,roleOR[普通用户,数据管理员]
  9. /page/listItems* = authc,roleOR[数据管理员,普通用户]
  10. /page/showItem* = authc,roleOR[数据管理员,普通用户]
  11. /page/updateItem*=authc,roles[数据管理员]
  12. </value>
  13. </property>

 

本教程采用动态加载,你可以从数据库里读取然后拼接成shiro要的数据。

 

 

 
  1. <property name="filterChainDefinitions" value="#\{shiroManager.loadFilterChainDefinitions()\}"/>

 

配置文件方式加载详细讲解:http://www.sojson.com/blog/148

五、Shiro 自定义权限校验Filter定义,及功能实现。

Shrio Filter在package:com.sojson.core.shiro.filter,具体配置在spring-shiro.xml中。定义了5个拦截器,具体功能看代码以及代码注释。

 

 
  1. <bean id="shiroManager" class="com.sojson.core.shiro.service.impl.ShiroManagerImpl"/>
  2. <bean id="login" class="com.sojson.core.shiro.filter.LoginFilter"/>
  3. <bean id="role" class="com.sojson.core.shiro.filter.RoleFilter"/>
  4. <bean id="permission" class="com.sojson.core.shiro.filter.PermissionFilter"/>
  5. <bean id="simple" class="com.sojson.core.shiro.filter.SimpleAuthFilter"/>
 
  1. <property name="filters">
  2. <util:map>
  3. <entry key="login" value-ref="login"></entry>
  4. <entry key="role" value-ref="role"></entry>
  5. <entry key="simple" value-ref="simple"></entry>
  6. <entry key="permission" value-ref="permission"></entry>
  7. </util:map>
  8. </property>

 

六、Shiro Ajax请求权限不满足,拦截后解决方案。

这里有一个前提,我们知道Ajax不能做页面redirectforward跳转,所以Ajax请求假如没登录,那么这个请求给用户的感觉就是没有任何反应,而用户又不知道用户已经退出了。解决代码如下:

 

 
  1. //Java代码,判断如果是Ajax请求,然后并且没登录,那么就给予返回JSON,login_status = 300,message = 当前用户没有登录!
  2. if (ShiroFilterUtils.isAjax(request)) {// ajax请求
  3. Map<String,String> resultMap = new HashMap<String, String>();
  4. LoggerUtils.debug(getClass(), "当前用户没有登录,并且是Ajax请求!");
  5. resultMap.put("login_status", "300");
  6. resultMap.put("message", "\u5F53\u524D\u7528\u6237\u6CA1\u6709\u767B\u5F55\uFF01");//当前用户没有登录!
  7. ShiroFilterUtils.out(response, resultMap);
  8. }

 

 

 
  1. //前端代码
  2. if(result.login_status == 300){
  3. layer.msg(result.message);//当前用户没有登录!
  4. }

 

七、Shiro Freemarker标签使用。

Freemarker使用Shiro 标签的介绍:http://www.sojson.com/blog/143

八、Shiro JSP标签使用。

JSP使用Shiro 标签的介绍:http://www.sojson.com/blog/144

九、Shiro 登录后跳转到最后一个访问的页面。

Java  中就可以这样获取上一个地址:

 

 
  1. //上一个浏览的非Ajax的地址,在登录后,取得地址,如果不为null,那么就跳转过去。
  2. String url = (String) request.getAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE);
  3. //shiro也有他的方法。详细看下面。

 

如果需要保存登录之前的Request信息,那么需要在Login拦截的Filter中先保存:

 

 
  1. @Override
  2. protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
  3. throws Exception {
  4. //保存Request和Response,登录后可以取到
  5. saveRequestAndRedirectToLogin(request, response);
  6. return Boolean.FALSE ;
  7. }
  8. //登录后,取到之前的Request中的一些信息。
  9. SavedRequest saveRequest = WebUtils.getSavedRequest(request);
  10. saveRequest.getMethod();//之前的请求方法
  11. saveRequest.getQueryString();//之前请求的条件
  12. saveRequest.getRequestURI();//之前请求的路径
  13. saveRequest.getRequestUrl();//之前请求的全路径

 

十、用户禁止登录Demo

这个功能其实是一个改变用户数据库表里的一个字段,本Demo中:1:有效,0:禁止登录

然后踢出用户登录状态。代码详细请查看CustomSessionManager.java类的forbidUserById(Long id, Long status)方法。

而再次登录的话,需要再登录,而登录的地方限制了用户状态为(0:禁止登录)的用户登录。

 
  1. /**
  2. * 查询要禁用的用户是否在线。
  3. * @param id 用户ID
  4. * @param status 用户状态
  5. */
  6. public void forbidUserById(Long id, Long status) {
  7. //获取所有在线用户
  8. for(UserOnlineBo bo : getAllUser()){
  9. Long userId = bo.getId();
  10. //匹配用户ID
  11. if(userId.equals(id)){
  12. //获取用户Session
  13. Session session = shiroSessionRepository.getSession(bo.getSessionId());
  14. //标记用户Session
  15. SessionStatus sessionStatus = (SessionStatus) session.getAttribute(SESSION_STATUS);
  16. //是否踢出 true:有效,false:踢出。
  17. sessionStatus.setOnlineStatus(status.intValue() == 1);
  18. //更新Session
  19. customShiroSessionDAO.update(session);
  20. }
  21. }
  22. }

十一、在线显示,在线用户管理(踢出登录)。

上面的功能依赖这个功能。从Redis中获取所有有效的Session

 
  1. /**
  2. * 获取所有的有效Session用户
  3. * @return
  4. */
  5. public List getAllUser() {
  6. //获取所有session
  7. Collection sessions = customShiroSessionDAO.getActiveSessions();
  8. List list = new ArrayList();
  9.  
  10. for (Session session : sessions) {
  11. UserOnlineBo bo = getSessionBo(session);
  12. if(null != bo){
  13. list.add(bo);
  14. }
  15. }
  16. return list;
  17. }

踢出后,不能直接退出,要不然用户感觉莫名其妙。所有增加了一个Filter。SimpleAuthFilter.java如果标记为踢出,会提示用户。具体查看源码以及配合项目的使用。

十二、登录注册密码加密传输。

这个地方好多人纠结的。比如密码过于简单,即使加密后也能破解。如我们把密码:123456,加密后就是:e10adc3949ba59abbe56e057f20f883e

这个很容易被识别,导致不安全,现在市面上的MD5破解其实就是把常用的数字,字母进行先加密,然后对比,美其名曰破解MD5。

那怎么能让用户即使使用很简单的密码,也发现不了?

本Demo的实现方式是:MD5(登录帐号 + “固定值” + 密码),把这个作为密码,这样,基本是不可能猜的出来。

 

 
  1. //Java代码。UserManager.md5Pswd(UUser user);
  2. /**
  3. * 加工密码,和登录一致。
  4. * @param user
  5. * @return
  6. */
  7. public static UUser md5Pswd(UUser user){
  8. //密码为 email + '#' + pswd,然后MD5
  9. user.setPswd(md5Pswd(user.getEmail(),user.getPswd()));
  10. return user;
  11. }
  12. /**
  13. * 字符串返回值
  14. * @param email
  15. * @param pswd
  16. * @return
  17. */
  18. public static String md5Pswd(String email ,String pswd){
  19. pswd = String.format("%s#%s", email,pswd);
  20. pswd = MathUtil.getMD5(pswd);
  21. return pswd;
  22. }
 
  1. //JS代码
  2. var pswd = MD5(username +"#" + password);

 

十三、密码修改。

不讲了,和上面原理一致,然后具体看Demo。

十四、用户个人中心。

包含的功能有[个人资料,资料修改,密码修改,我的权限],具体看Demo。

十五、权限的增删改查。

Demo的设计是遵循RBAC3的思想。http://www.sojson.com/blog/142

RBAC个人理解介绍:http://www.sojson.com/blog/141

具体实现看Demo。

十六、角色的增删改查。

 

十七、权限->角色->用户之间的关系维护。

把权限赋给角色。

把角色赋给用户。

十八、管理员权限的自动添加

这里每次添加一个权限,都会添加到“管理员”角色下,保证“管理员”角色拥有最大权限。

十九、Spring定时任务数据初始化。

这个Demo因为是开放的,所以创建了一个定时任务。每20分钟执行一次,用Mysql存储过程重新创建表,重新插入初始化数据。

具体数据看项目中的init/sql下的tables.sql(初始化表),init.data.sql(初始化数据)。

 

 
  1. //定时任务配置文件spring-timer.xml
  2. <task:executor id="executor" pool-size="5" />
  3. <task:scheduler id="scheduler" pool-size="10" />
  4. <task:annotation-driven executor="executor" scheduler="scheduler" />
  5. //Java 代码 RoleServiceImpl.java
  6. /**
  7. * 每20分钟执行一次
  8. */
  9. @Override
  10. @Scheduled(cron = "0 0/20 * * * ? ")
  11. public void initData() {
  12. roleMapper.initData();
  13. }

 

二十、集成验证码。

shiro

项目中package:com.sojson.common.utils.vcode包是验证码的封装包。

并且提供了一个VerifyCodeUtils.java 的验证码工具类。

使用方法参见:CommonController.java类中的getVCode()方法和getGifCode()方法。

验证码详细介绍
Java生成验证码合集(一)简单版
Java生成验证码合集(二)GJF版

如果不是Maven项目,下载依赖包。

依赖Jar包下载:

http://pan.baidu.com/s/1c2LUumW 提取密码:3kv8、或者请加QQ群:259217951(群文件内有,有问题可以交流。)。

备注:点击文件名下载,附件源来自云端,只能在本站下载。复制下载链接无效。

Shrio + SSM框架 Demo 源码下载。

源码下载

Shiro_SSM_0.1版本下载

备注:点击文件名下载,附件源来自云端,只能在本站下载。复制下载链接无效

© 著作权归作者所有

8446666

8446666

粉丝 26
博文 9
码字总数 10298
作品 1
东城
技术主管
私信 提问
加载中

评论(3)

8446666
8446666 博主
官方已经更新了,请下载新版本和新文档看这个地址:http://www.sojson.com/shiro
8446666
8446666 博主

引用来自“aspboy”的评论

非常不错
谢谢!有问题加群交流!
aspboy
aspboy
非常不错
Spring Boot Shiro 权限管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/catoop/article/details/50520958 本来是打算接着写关于数据库方面,集成MyBatis的,刚好赶上朋友问到Shiro权...

单红宇
2016/01/14
0
0
SpringMvc + Shiro[数据库存权限] 配置 ;[附git.oschina的项目地址]

一 shiro简介 apache shiro 是功能强大并且容易集成的开源权限框架,它能够完成认证、授权、加密、会话管理等功能。认证和授权为权限控制的核心,简单来说,“认证”就是证明“你是谁?” We...

王庭
2015/10/28
11K
2
shiro实战系列(一)之入门实战

一、什么是shiro? Apache Shiro 是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密。 Apache Shiro 的首要目标是易于使用和理解。安全有时候是很复杂的,...

youcongtech
2018/06/03
0
0
结合SSM框架讲解Shiro案例--Shiro Demo

本教程结合SSM(SpringMVC + Mybatis)框架讲解Shiro(Shiro是 Java 的一个安全框架。我们经常看到它被拿来和 Spring 的 Security 来对比。),讲解的内容有自定义Shiro拦截器,Shiro Freem...

8446666
2016/06/29
28.8K
11
huangdf/seezoon-framework-all

项目介绍 基于spring,mybatis,shiro面向接口开发的的一套后台管理系统,方便快速开发;采用常用的技术栈,降低学习成本,项目完全前后端分离,后端定义统一的接口格式,统一参数校验,统一权...

huangdf
2018/04/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CSS--属性

一、溢出 当内容多,元素区域小的时候,就会产生溢出效果,默认是纵向溢出 横向溢出:在内容和容器之间再套一层容器,并且内部容器要比外部容器宽 属性:overflow/overflow-x/overflow-y 取值...

wytao1995
45分钟前
4
0
Confluence 6.15 使用附件宏

希望添加附件宏到一个页面中: 从编辑工具栏中,选择 插入(Insert) > 其他宏(Other Macros) 找到并且选择需要的宏。 可用使用自动完成加快这个过程:输入 { 然后开始输入你希望插入的宏的...

honeymoose
今天
4
0
精华帖

第一章 jQuery简介 jQuery是一个JavaScript库 jQuery具备简洁的语法和跨平台的兼容性 简化了JavaScript的操作。 在页面中引入jQuery jQuery是一个JavaScript脚本库,不需要特别的安装,只需要...

流川偑
今天
6
0
语音对话英语翻译在线翻译成中文哪个方法好用

想要进行将中文翻译成英文,或者将英文翻译成中文的操作,其实有一个非常简单的工具就能够帮助完成将语音进行翻译转换的软件。 在应用市场或者百度手机助手等各大应用渠道里面就能够找到一款...

401恶户
今天
3
0
jenkins 插件下载加速最终方案

推荐做法 1、告诉jenkins 我哪些插件需要更新 jenkins插件清华大学镜像地址 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json 1.进入jenkins系统管理 2.进入插件管...

vasks
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部