Shiro Demo 结合SSM框架讲解Shiro案例开源项目

我要开发同款
匿名用户2016年06月29日
155阅读

技术信息

开源地址
https://github.com/pwnsdx/RandomDNS
授权协议
GPL

作品详情

本教程结合SSM(SprigMVC+Mybatis)框架讲解Shiro(Shiro是Java 的一个安全框架。我们经常看到它被拿来和Sprig 的Security 来对比。),讲解的内容有自定义Shiro拦截器,ShiroFreemarker标签,ShiroJSP标签,权限控制讲解,并提供ShiroDemo下载。

ShiroDemo环境准备

开发工具:Eclipse、MyEclipse、Idea等等。

依赖第三方:Mysql5.0以上、Redis。

需要的配置:jdbc.properties中配置Mysql的信息、sprig-cache.xml配置Redis配置,如果是默认配置,就不用换,RedisWidows安装:https://www.sojso.com/blog/110.html。

注意:官方网站已经更新了第二个版本:https://www.sojso.com/shiro 

申明:请看完本页面的所有细节,对你掌握这个项目来说很重要,别一上来就搞,你不爽,我也不爽。

本项目理论上,只需要一个Redis,然后一个Mysql和一个有Mave环境的开发工具即可运行起来。

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

ShiroDemo非Mave项目依赖包下载:点我下载

ShiroDemo源码下载下载:点我(云端下载)

Github0.1版本下载:https://github.com/baichegzhou/SprigMVC-Mybatis-shiro

Github0.2版本下载:https://github.com/baichegzhou/SprigMVC-Mybatis-Shiro-redis-0.2

ShiroDemo0.2版本介绍:https://www.sojso.com/blog/165.html

ShiroDemo0.2版本主要解决的问题为0.1版本出现的问题和BUG,然后添加了一个功能--单个帐号登录限制问题,具体查看上面的介绍。

ShiroDemo环境准备,建议使用0.2版本,这样你会遇到较少问题。

开发工具:Eclipse、MyEclipse、Idea等等。

依赖第三方:Mysql5.0以上、Redis。

需要的配置:jdbc.properties中配置Mysql的信息、sprig-cache.xml配置Redis配置,如果是默认配置,就不用换,RedisWidows安装:https://www.sojso.com/blog/110.html。

注意:0.1版本访问不要带项目路径访问。比如用:https://localhost:8080访问,别带设置带项目名称,如:https://localhost:8080/shiro.demo/这样是不对的。。也就是要把项目部署到Root下,也就是根目录下。0.2版本已经解决该问题了。主流的工具部署到Root下的方法:

IDEA部署项目到root

Eclipse部署项目到root

MyEclipse部署项目到root

Shiro简介

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

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

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

本教程环境。

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

本教程开发工具是Myecilpse8.5。

本教程编码格式为UTF-8。

本教程JDK为1.7。

本教程Sprig版本为4.2.5。

前端页面采用Bootstarp3.2。

本教程包含的内容。

SSM(SprigMVC+Sprig+Mybatis)框架的增删改查(含分页),所以如果框架小白也是可以看看的。

View层主要是Freemarker,但是为了考虑到好多人还使用的是JSP,也有一个页面是用JSP实现的,并且框架支持Freemarker和JSP双View展示(优先找Freemarker)。

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

Shiro初始权限动态加载。

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

ShiroAjax请求权限不满足,拦截后解决方案。

ShiroFreemarker标签使用。

ShiroJSP标签使用。

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

用户禁止登录Demo。

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

登录注册密码加密传输Demo(详细请见下面讲解)。

密码修改。

用户个人中心。

权限的增删改查。

角色的增删改查。

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

管理员权限的自动添加(当有一个权限创建,自动添加到管理员角色下,保证管理员是最大权限)。

Sprig定时任务数据化数据。

集成多种验证码(包括动态的gif验证码哦)。

一个帐号多处登录限制,踢出用户。

后续会陆陆续续升级......

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

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

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

二、View层Freemarker,JSP

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

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

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

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

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

/** = ao       /page/logi.jsp = ao       /page/register/* = ao       /page/idex.jsp = authc       /page/addItem* = authc,roles[数据管理员]       /page/file* = authc,roleOR[普通用户,数据管理员]       /page/listItems* = authc,roleOR[数据管理员,普通用户]       /page/showItem* = authc,roleOR[数据管理员,普通用户]       /page/updateItem*=authc,roles[数据管理员]

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

<property ame="filterChaiDefiitios" value="#\{shiroMaager.loadFilterChaiDefiitios()\}"/>

配置文件方式加载详细讲解:https://www.sojso.com/blog/148.html

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

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

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

    <bea id="shiroMaager" class="com.sojso.core.shiro.service.impl.ShiroMaagerImpl"/>      <bea id="logi" class="com.sojso.core.shiro.filter.LogiFilter"/>      <bea id="role" class="com.sojso.core.shiro.filter.RoleFilter"/>      <bea id="permissio" class="com.sojso.core.shiro.filter.PermissioFilter"/>      <bea id="simple" class="com.sojso.core.shiro.filter.SimpleAuthFilter"/><property ame="filters">      <util:map>       <etry key="logi" value-ref="logi"></etry>       <etry key="role" value-ref="role"></etry>       <etry key="simple" value-ref="simple"></etry>       <etry key="permissio" value-ref="permissio"></etry>       </util:map>  </property>六、ShiroAjax请求权限不满足,拦截后解决方案。

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

//Java代码,判断如果是Ajax请求,然后并且没登录,那么就给予返回JSON,logi_status = 300,message = 当前用户没有登录!      if (ShiroFilterUtils.isAjax(request)) {// ajax请求       MapresultMap = ew HashMap();       LoggerUtils.debug(getClass(), "当前用户没有登录,并且是Ajax请求!");       resultMap.put("logi_status", "300");       resultMap.put("message", "\u5F53\u524D\u7528\u6237\u6CA1\u6709\u767B\u5F55\uFF01");//当前用户没有登录!       ShiroFilterUtils.out(respose, resultMap);      }//前端代码 if(result.logi_status == 300){    layer.msg(result.message);//当前用户没有登录!  }七、ShiroFreemarker标签使用。

Freemarker使用Shiro标签的介绍:https://www.sojso.com/blog/143.html

八、ShiroJSP标签使用。

JSP使用Shiro标签的介绍:https://www.sojso.com/blog/144.html

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

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

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

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

@Override      protected boolea oAccessDeied(ServletRequest request, ServletRespose respose)       throws Exceptio {       //保存Request和Respose,登录后可以取到       saveRequestAdRedirectToLogi(request, respose);       retur Boolea.FALSE ;      }      //登录后,取到之前的Request中的一些信息。      SavedRequest saveRequest = WebUtils.getSavedRequest(request);      saveRequest.getMethod();//之前的请求方法      saveRequest.getQueryStrig();//之前请求的条件      saveRequest.getRequestURI();//之前请求的路径      saveRequest.getRequestUrl();//之前请求的全路径十、用户禁止登录Demo

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

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

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

   /**       * 查询要禁用的用户是否在线。       * @param id用户ID       * @param status用户状态       */      public void forbidUserById(Log id, Log status) {       //获取所有在线用户       for(UserOlieBo bo : getAllUser()){       Log userId = bo.getId();       //匹配用户ID       if(userId.equals(id)){       //获取用户Sessio       Sessio sessio = shiroSessioRepository.getSessio(bo.getSessioId());       //标记用户Sessio       SessioStatus sessioStatus = (SessioStatus) sessio.getAttribute(SESSION_STATUS);       //是否踢出 true:有效,false:踢出。       sessioStatus.setOlieStatus(status.itValue() == 1);       //更新Sessio       customShiroSessioDAO.update(sessio);       }       }      }十一、在线显示,在线用户管理(踢出登录)。

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

/**       * 获取所有的有效Sessio用户       * @retur       */      public List getAllUser() {       //获取所有sessio       Collectio sessios = customShiroSessioDAO.getActiveSessios();       List list = ew ArrayList();              for (Sessio sessio : sessios) {       UserOlieBo bo = getSessioBo(sessio);       if(ull != bo){       list.add(bo);       }       }       retur list;      }

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

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

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

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

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

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

//Java代码。UserMaager.md5Pswd(UUser user);      /**       * 加工密码,和登录一致。       * @param user       * @retur       */      public static UUser md5Pswd(UUser user){       //密码为   email + '#' + pswd,然后MD5       user.setPswd(md5Pswd(user.getEmail(),user.getPswd()));       retur user;      }      /**       * 字符串返回值       * @param email       * @param pswd       * @retur       */      public static Strig md5Pswd(Strig email ,Strig pswd){       pswd = Strig.format("%s#%s", email,pswd);       pswd = MathUtil.getMD5(pswd);       retur pswd;      }//JS代码  var pswd = MD5(userame +"#" + password);十三、密码修改。

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

十四、用户个人中心。

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

十五、权限的增删改查。

本Demo的设计是遵循RBAC3的思想。https://www.sojso.com/blog/142.html

RBAC个人理解介绍:https://www.sojso.com/blog/141.html

具体实现看Demo。

十六、角色的增删改查。

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

把权限赋给角色。

把角色赋给用户。

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

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

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

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

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

//定时任务配置文件sprig-timer.xml//Java 代码 RoleServiceImpl.java      /**       * 每20分钟执行一次       */      @Override      @Scheduled(cro = "0 0/20 * * * ? ")      public void iitData() {       roleMapper.iitData();      }二十、集成验证码。

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

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

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

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

二十一、一个帐号多处登录限制,踢出用户。

项目中我们会用到单点登录,还有用到单个账号怎么限制同时只能一个人在线?

Shiro教程(十一)Shiro控制并发登录人数限制实现,登录踢出实现:https://www.sojso.com/blog/158.html

功能介绍

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

示例图片

声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论