简介

  • Shiro的组件都是Javabean/pojo式的组件,所以非常容易使用Spring进行组件管理,可以非常方便得从ini配置转为Spring配置(如xml配置文件)。

JavaSE

  • 依赖

    <!--单元测试-->
    <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.9</version><scope>test</scope>
    </dependency>
    <!--集成Spring做测试必备的依赖,比如要注入Spring容器中的bean-->
    <dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>4.2.4.RELEASE</version><scope>test</scope>
    </dependency>
    <dependency> <!--用于开启事务,否则测试将无法自动回滚--><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>4.2.4.RELEASE</version>
    </dependency>
    <dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1.3</version>
    </dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.0</version>
    </dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.2.2</version>
    </dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>1.2.2</version>
    </dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.2.4.RELEASE</version>
    </dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-quartz</artifactId><version>1.2.2</version>
    </dependency>
    <dependency> <!--使用quartz要用到的--><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.1</version>
    </dependency><!--mysql数据库及druid连接池-->
    <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.25</version>
    </dependency>
    <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>0.2.23</version>
    </dependency>
    <dependency> <!--使用JdbcTemplate,方便数据库操作--><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>4.2.4.RELEASE</version>
    </dependency>
    
  • spring-shiro.xml:取代ini配置,提供了普通JavaSE应用的Spring配置。

    <!-- 缓存管理器 使用Ehcache实现 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"><property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
    </bean><!-- 凭证匹配器 -->
    <bean id="credentialsMatcher" class="
    com.github.zhangkaitao.shiro.chapter12.credentials.RetryLimitHashedCredentialsMatcher"><constructor-arg ref="cacheManager"/><property name="hashAlgorithmName" value="md5"/><property name="hashIterations" value="2"/><property name="storedCredentialsHexEncoded" value="true"/>
    </bean><!-- Realm实现 -->
    <bean id="userRealm" class="com.github.zhangkaitao.shiro.chapter12.realm.UserRealm"><property name="userService" ref="userService"/><property name="credentialsMatcher" ref="credentialsMatcher"/><property name="cachingEnabled" value="true"/><property name="authenticationCachingEnabled" value="true"/><property name="authenticationCacheName" value="authenticationCache"/><property name="authorizationCachingEnabled" value="true"/><property name="authorizationCacheName" value="authorizationCache"/>
    </bean>
    <!-- 会话ID生成器 -->
    <bean id="sessionIdGenerator"
    class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
    <!-- 会话DAO -->
    <bean id="sessionDAO"
    class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"><property name="activeSessionsCacheName" value="shiro-activeSessionCache"/><property name="sessionIdGenerator" ref="sessionIdGenerator"/>
    </bean>
    <!-- 会话验证调度器 -->
    <bean id="sessionValidationScheduler"
    class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler"><property name="sessionValidationInterval" value="1800000"/><property name="sessionManager" ref="sessionManager"/>
    </bean>
    <!-- 会话管理器 -->
    <bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager"><property name="globalSessionTimeout" value="1800000"/><property name="deleteInvalidSessions" value="true"/><property name="sessionValidationSchedulerEnabled" value="true"/><property name="sessionValidationScheduler" ref="sessionValidationScheduler"/><property name="sessionDAO" ref="sessionDAO"/>
    </bean>
    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager"><property name="realms"><list><ref bean="userRealm"/></list></property><property name="sessionManager" ref="sessionManager"/><property name="cacheManager" ref="cacheManager"/>
    </bean>
    <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="staticMethod"
    value="org.apache.shiro.SecurityUtils.setSecurityManager"/><property name="arguments" ref="securityManager"/>
    </bean>
    <!-- Shiro生命周期处理器-->
    <bean id="lifecycleBeanPostProcessor"
    class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    
  • 其中,Realm实现需要注入userService的bean,它不在本配置文件,而在以下spring-beans.xml中,一样可以找到的。

  • spring-beans.xml

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://127.0.0.1:3306/shiro"/><property name="username" value="root"/><property name="password" value="123456"/>
    </bean><!-- Base DAO: abstract="true"即该类不能被实例化,默认false;抽象bean可以不映射任何类 -->
    <bean id="baseDao" abstract="true"><property name="dataSource" ref="dataSource"/>
    </bean><!-- DAO -->
    <bean id="permissionDao" class="com.haien.shirochapter12.dao.impl.PermissionDaoImpl" parent="baseDao"/>
    <bean id="roleDao" class="com.haien.shirochapter12.dao.impl.RoleDaoImpl" parent="baseDao"/>
    <bean id="userDao" class="com.haien.shirochapter12.dao.impl.UserDaoImpl" parent="baseDao"/><!-- Service -->
    <bean id="permissionService" class="com.haien.shirochapter12.service.impl.PermissionServiceImpl"><property name="permissionDao" ref="permissionDao"/>
    </bean><bean id="roleService" class="com.haien.shirochapter12.service.impl.RoleServiceImpl"><property name="roleDao" ref="roleDao"/>
    </bean><!--帮助加密密码-->
    <bean id="passwordHelper" class="com.haien.shirochapter12.service.impl.PasswordHelper"><property name="algorithmName" value="md5"/><property name="hashIterations" value="2"/>
    </bean><bean id="userService" class="com.haien.shirochapter12.service.impl.UserServiceImpl"><property name="userDao" ref="userDao"/><property name="passwordHelper" ref="passwordHelper"/>
    </bean><!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" />
    </bean>
    <!--开启事务-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
  • 分别写User,Role,Permission的entity,dao,service层、实现身份验证和授权的UserRealm。
  • ShiroTest:测试类,测试前删除各表数据,重新插入,分配角色和用户给用户;主要测试方法则是以某个用户登录,判断是否拥有权限。
@Test
public void test() {Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(u1.getUsername(), password);subject.login(token);Assert.assertTrue(subject.isAuthenticated());subject.checkRole("admin");subject.checkPermission("user:create");userService.changePassword(u1.getId(), password + "1");userRealm.clearCache(subject.getPrincipals());token = new UsernamePasswordToken(u1.getUsername(), password + "1");subject.login(token);
}

web应用

  • spring-shiro-web.xml:web应用和JavaSE应用的shiro配置是类似的,此处提供一些不一样的配置.

    <!-- web:会话Cookie模板 -->
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie"><!--设置cookie名,默认为JSESSIONID--><constructor-arg value="sid"/><!--设置cookie过期时间,单位秒,默认-1,即关闭浏览器时过期--><property name="httpOnly" value="true"/><!--true表示客户端不会暴露脚本代码,有助于减少某些类型的跨站点脚本攻击,Servlet2.5及以上才支持--><property name="maxAge" value="180000"/>
    </bean><!-- web:会话管理器,使用用于web环境的DefaultWebSessionManager -->
    <bean id="sessionManager"class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <!--自己管理--><property name="globalSessionTimeout" value="1800000"/><property name="deleteInvalidSessions" value="true"/><property name="sessionValidationSchedulerEnabled" value="true"/><property name="sessionValidationScheduler" ref="sessionValidationScheduler"/><property name="sessionDAO" ref="sessionDAO"/><property name="sessionIdCookieEnabled" value="true"/><property name="sessionIdCookie" ref="sessionIdCookie"/>
    </bean><!-- web:安全管理器,使用用于web环境的DefaultWebSecurityManager -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="userRealm"/><property name="sessionManager" ref="sessionManager"/><property name="cacheManager" ref="cacheManager"/>
    </bean><!-- web:基于Form表单的身份验证过滤器 -->
    <bean id="formAuthenticationFilter"class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"><property name="usernameParam" value="username"/><property name="passwordParam" value="password"/><property name="loginUrl" value="/login.jsp"/>
    </bean><!-- web:Shiro的Web过滤器,使用ShiroFilterFactoryBean创建ShiroFilter过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager"/><property name="loginUrl" value="/login.jsp"/><property name="unauthorizedUrl" value="/unauthorized.jsp"/><!--定义自己的过滤器--><property name="filters"><util:map><entry key="authc" value-ref="formAuthenticationFilter"/></util:map></property><property name="filterChainDefinitions"><value>/index.jsp = anon/unauthorized.jsp = anon/login.jsp = authc/logout = logout/** = user</value></property>
    </bean>
    
  • 会话管理器和安全管理器都要换成web环境下的,还要加个过滤器。
  • 过滤器使用ShiroFilterFactoryBean来创建ShiroFilter过滤器,filters属性用于定义自己的过滤器,即ini配置中的[filters],filterChianDefinitions用于声明url和filter的关系,即ini配置中的[urls]。
  • web.xml:

    <!-- Spring配置文件开始  --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-beans.xml,classpath:spring-shiro-web.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- Spring配置文件结束 --><!-- shiro 安全过滤器 --><!-- The filter-name matches name of a 'shiroFilter' bean inside applicationContext.xml --><filter><filter-name>shiroFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><async-supported>true</async-supported><init-param><param-name>targetFilterLifecycle</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>shiroFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><servlet><servlet-name>spring</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup><async-supported>true</async-supported></servlet><servlet-mapping><servlet-name>spring</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
    
  • DelegatingFilterProxy:自动到Spring容器中查找名为shiroFilter的bean(它就定义在spring-shiro-web.xml中),并把filter请求交给它处理。

  • spring-mvc.xml:

    <!--use-default-filters:使用默认过滤器,它会扫描包含@Service、@Component、
    @Repository、@Controller注解的类;不使用则需用include-filter指定扫描哪些类-->
    <context:component-scan base-package="com.haien.shirochapter12.web" use-default-filters="false"><!--指定只扫描base-package下有@Controller的类--><context:include-filter type="annotation"expression="org.springframework.stereotype.Controller"/><!--指定只扫描base-package下有@ControllerAdvice的类--><context:include-filter type="annotation"expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
    </context:component-scan><!--添加shiro spring aop权限注解的支持,即使用注解式授权-->
    <aop:config proxy-target-class="true"></aop:config> <!--表示使用代理类-->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager"/>
    </bean><!--启动SpringMvc注解功能,完成请求和注解controller类的映射-->
    <mvc:annotation-driven/>
    <mvc:view-controller path="/" view-name="index"/> <!--url映射视图,无需通过控制器--><!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用html)- -->
    <bean id="defaultViewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/><property name="contentType" value="text/html"/><property name="prefix" value="/"/><property name="suffix" value=".jsp"/>
    </bean><!-- 控制器异常处理(好像不写也可以) -->
    <bean id="exceptionHandlerExceptionResolver" class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
    </bean>
    <bean class="com.haien.shirochapter12.web.exception.DefaultExceptionHandler"/>
    
  • AnnotationController:上面开启了Shiro注解式访问控制,那么接下来就可以在Controller中使用注解

@Controller
public class AnnotationController {@RequestMapping("/hello1")public String hello1() {SecurityUtils.getSubject().checkRole("admin");return "success";}@RequiresRoles("admin")@RequestMapping("/hello2")public String hello2() {return "success";}
}
  • DefaultExceptionHandler:全局异常处理,无权限则返回unauthorized.jsp页面,提示用户无权限。目前数据库只有zhang/123拥有权限,其他如li/123都没有权限。
@ControllerAdvice
public class DefaultExceptionHandler {@ExceptionHandler({UnauthorizedException.class}) //处理controller抛出的该类异常及其子类@ResponseStatus(HttpStatus.UNAUTHORIZED)public ModelAndView processUnauthenticatedException(NativeWebRequest request,UnauthorizedException e){ModelAndView mv=new ModelAndView();mv.addObject("exception",e);mv.setViewName("unauthorized");return mv;}
}
  • 代码示例:ideaProjects/shirochapter12
  • 《跟我学shiro第十二章》

Shiro第十二章-与Spring集成、配置文件初解相关推荐

  1. 第十二章:Spring Cloud Config Server 的配置

    ###1.为什么要使用config 集中管理 不通环境不通配置 运行期间动态调整配置 自动刷新 ###2.用法入门 导入pom <dependency><groupId>org ...

  2. 《深入理解 Spring Cloud 与微服务构建》第十二章 服务注册和发现 Consul

    <深入理解 Spring Cloud 与微服务构建>第十二章 服务注册和发现 Consul 文章目录 <深入理解 Spring Cloud 与微服务构建>第十二章 服务注册和发 ...

  3. 2017.2.12 开涛shiro教程-第七章-与Web集成

    2017.2.9 开涛shiro教程-第七章-与Web集成(一) 原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. ...

  4. 简述sd卡2.0协议_【正点原子FPGA连载】第十二章SD卡读写TXT文本实验-领航者 ZYNQ 之嵌入式开发指南...

    1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下 ...

  5. 《构建之法》第十一、十二章学习总结

    第十一章的内容是软件设计与实现. 在第一节中,讲的是关于分析和设计方法,向我们介绍在"需求分析"."设计与实现"阶段."测试""发 ...

  6. 第十二章_网络搭建及训练

    文章目录 第十二章 网络搭建及训练 CNN训练注意事项 第十二章 TensorFlow.pytorch和caffe介绍 12.1 TensorFlow 12.1.1 TensorFlow是什么? 12 ...

  7. 《Kotlin 程序设计》第十二章 Kotlin的多线程:协程(Coroutines)

    第十二章 Kotlin的多线程:协程(Coroutines) Kotlin 1.1 introduced coroutines, a new way of writing asynchronous, ...

  8. 【信息系统项目管理师】第二十二章 信息系统安全管理(考点汇总篇)

    [信息系统项目管理师]第二十二章 信息系统安全管理(考点汇总篇) 考点分析与预测 信息安全为高级科目独有的章节,在第三版教材中有66页的内容.需要掌握的知识点非常多,且知识点非常散,在考试中上午一般考 ...

  9. 在Jetson Nano上学习ROS的记录(版本Ubuntu18.04,课程来源赵虚左老师的《ROS理论与实践》)第十二章 机器人导航(仿真)

    系列文章目录 第一章 ROS空间创建.helloworld的实现.开启多个节点 第二章 话题通信 第三章 服务通信 第四章 参数服务器 第五章 常用指令 第六章 通信机制实操 第七章 ROS通信机制进 ...

最新文章

  1. CNN交通场景解析--Spatial as Deep: Spatial CNN for Traffic Scene Understanding
  2. 131125 - 关于对“一次元”、“二次元”、“三次元”的兴趣变化的奇思妙想
  3. JAVA入门级教学之(定义一个学生类)
  4. 面试题 04.06. 后继者
  5. 吴恩达|机器学习作业6.1.SVM建立垃圾邮件分类器
  6. Silverlight 密码框 Focus
  7. nmon在linux系统中的应用
  8. eclipse中误删除的java文件 代码如何恢复
  9. tidyverse —— tidyr包
  10. win7一键清理系统垃圾Bat脚本
  11. 笔记本连接无线网络后通过有线网口共享网络
  12. js设为首页和加入收藏
  13. Qt 人脸对比体温检测软件(界面酷炫),千人毫秒响应
  14. Git reset --hard commit_id 和 git reset --soft commit_id
  15. 自动钉木箱机器人_一种木箱生产用自动钉装设备的制作方法
  16. 【颜纠日记】分享5个理财规划步骤,5招更早过上理想生活
  17. asp.net(c#)中IsPostBack是什么意思
  18. 插入u盘计算机未响应,U盘插入win7电脑没反应如何解决 Win7插入U盘没反应怎么办...
  19. SQLServer将日期转换成字符串格式
  20. oraclenbsp;命名规范

热门文章

  1. Win10桌面图标无法拖动
  2. WPS文字表格外计算功能配合书签使用公式轻松实现
  3. zblog去除底部版权信息 “请勿修改或删除主题版权及作者信息”
  4. Linux攻关之基础模块一 系统准备
  5. VTS-DEBUG VtsHalCameraProviderV2_4TargetTest CameraHidlTest.noHal1AfterP FAIL
  6. 云计算 大数据 人工智能 三者之间关系
  7. 人工智能导论:清览作业
  8. 数据库常用的sql语句名称大全
  9. Code_Aster comm命令文件结构与说明(by Yang 2017.3.30)
  10. Java死循环,循环嵌套,break,continue