Shiro第十二章-与Spring集成、配置文件初解
简介
- 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集成、配置文件初解相关推荐
- 第十二章:Spring Cloud Config Server 的配置
###1.为什么要使用config 集中管理 不通环境不通配置 运行期间动态调整配置 自动刷新 ###2.用法入门 导入pom <dependency><groupId>org ...
- 《深入理解 Spring Cloud 与微服务构建》第十二章 服务注册和发现 Consul
<深入理解 Spring Cloud 与微服务构建>第十二章 服务注册和发现 Consul 文章目录 <深入理解 Spring Cloud 与微服务构建>第十二章 服务注册和发 ...
- 2017.2.12 开涛shiro教程-第七章-与Web集成
2017.2.9 开涛shiro教程-第七章-与Web集成(一) 原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. ...
- 简述sd卡2.0协议_【正点原子FPGA连载】第十二章SD卡读写TXT文本实验-领航者 ZYNQ 之嵌入式开发指南...
1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下 ...
- 《构建之法》第十一、十二章学习总结
第十一章的内容是软件设计与实现. 在第一节中,讲的是关于分析和设计方法,向我们介绍在"需求分析"."设计与实现"阶段."测试""发 ...
- 第十二章_网络搭建及训练
文章目录 第十二章 网络搭建及训练 CNN训练注意事项 第十二章 TensorFlow.pytorch和caffe介绍 12.1 TensorFlow 12.1.1 TensorFlow是什么? 12 ...
- 《Kotlin 程序设计》第十二章 Kotlin的多线程:协程(Coroutines)
第十二章 Kotlin的多线程:协程(Coroutines) Kotlin 1.1 introduced coroutines, a new way of writing asynchronous, ...
- 【信息系统项目管理师】第二十二章 信息系统安全管理(考点汇总篇)
[信息系统项目管理师]第二十二章 信息系统安全管理(考点汇总篇) 考点分析与预测 信息安全为高级科目独有的章节,在第三版教材中有66页的内容.需要掌握的知识点非常多,且知识点非常散,在考试中上午一般考 ...
- 在Jetson Nano上学习ROS的记录(版本Ubuntu18.04,课程来源赵虚左老师的《ROS理论与实践》)第十二章 机器人导航(仿真)
系列文章目录 第一章 ROS空间创建.helloworld的实现.开启多个节点 第二章 话题通信 第三章 服务通信 第四章 参数服务器 第五章 常用指令 第六章 通信机制实操 第七章 ROS通信机制进 ...
最新文章
- CNN交通场景解析--Spatial as Deep: Spatial CNN for Traffic Scene Understanding
- 131125 - 关于对“一次元”、“二次元”、“三次元”的兴趣变化的奇思妙想
- JAVA入门级教学之(定义一个学生类)
- 面试题 04.06. 后继者
- 吴恩达|机器学习作业6.1.SVM建立垃圾邮件分类器
- Silverlight 密码框 Focus
- nmon在linux系统中的应用
- eclipse中误删除的java文件 代码如何恢复
- tidyverse —— tidyr包
- win7一键清理系统垃圾Bat脚本
- 笔记本连接无线网络后通过有线网口共享网络
- js设为首页和加入收藏
- Qt 人脸对比体温检测软件(界面酷炫),千人毫秒响应
- Git reset --hard commit_id 和 git reset --soft commit_id
- 自动钉木箱机器人_一种木箱生产用自动钉装设备的制作方法
- 【颜纠日记】分享5个理财规划步骤,5招更早过上理想生活
- asp.net(c#)中IsPostBack是什么意思
- 插入u盘计算机未响应,U盘插入win7电脑没反应如何解决 Win7插入U盘没反应怎么办...
- SQLServer将日期转换成字符串格式
- oraclenbsp;命名规范
热门文章
- Win10桌面图标无法拖动
- WPS文字表格外计算功能配合书签使用公式轻松实现
- zblog去除底部版权信息 “请勿修改或删除主题版权及作者信息”
- Linux攻关之基础模块一 系统准备
- VTS-DEBUG VtsHalCameraProviderV2_4TargetTest CameraHidlTest.noHal1AfterP FAIL
- 云计算 大数据 人工智能 三者之间关系
- 人工智能导论:清览作业
- 数据库常用的sql语句名称大全
- Code_Aster comm命令文件结构与说明(by Yang 2017.3.30)
- Java死循环,循环嵌套,break,continue