转发:https://www.iteye.com/blog/jinnianshilongnian-2029717

目录贴:跟我学Shiro目录贴

Shiro的组件都是JavaBean/POJO式的组件,所以非常容易使用Spring进行组件管理,可以非常方便的从ini配置迁移到Spring进行管理,且支持JavaSE应用及Web应用的集成。

在示例之前,需要导入shiro-spring及spring-context依赖,具体请参考pom.xml。

spring-beans.xml配置文件提供了基础组件如DataSource、DAO、Service组件的配置。

JavaSE应用

spring-shiro.xml提供了普通JavaSE独立应用的Spring配置:

  1. <!-- 缓存管理器 使用Ehcache实现 -->
  2. <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
  3. <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
  4. </bean>
  5. <!-- 凭证匹配器 -->
  6. <bean id="credentialsMatcher" class="
  7. com.github.zhangkaitao.shiro.chapter12.credentials.RetryLimitHashedCredentialsMatcher">
  8. <constructor-arg ref="cacheManager"/>
  9. <property name="hashAlgorithmName" value="md5"/>
  10. <property name="hashIterations" value="2"/>
  11. <property name="storedCredentialsHexEncoded" value="true"/>
  12. </bean>
  13. <!-- Realm实现 -->
  14. <bean id="userRealm" class="com.github.zhangkaitao.shiro.chapter12.realm.UserRealm">
  15. <property name="userService" ref="userService"/>
  16. <property name="credentialsMatcher" ref="credentialsMatcher"/>
  17. <property name="cachingEnabled" value="true"/>
  18. <property name="authenticationCachingEnabled" value="true"/>
  19. <property name="authenticationCacheName" value="authenticationCache"/>
  20. <property name="authorizationCachingEnabled" value="true"/>
  21. <property name="authorizationCacheName" value="authorizationCache"/>
  22. </bean>
  23. <!-- 会话ID生成器 -->
  24. <bean id="sessionIdGenerator"
  25. class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
  26. <!-- 会话DAO -->
  27. <bean id="sessionDAO"
  28. class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
  29. <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
  30. <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
  31. </bean>
  32. <!-- 会话验证调度器 -->
  33. <bean id="sessionValidationScheduler"
  34. class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
  35. <property name="sessionValidationInterval" value="1800000"/>
  36. <property name="sessionManager" ref="sessionManager"/>
  37. </bean>
  38. <!-- 会话管理器 -->
  39. <bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">
  40. <property name="globalSessionTimeout" value="1800000"/>
  41. <property name="deleteInvalidSessions" value="true"/>
  42. <property name="sessionValidationSchedulerEnabled" value="true"/>
  43. <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
  44. <property name="sessionDAO" ref="sessionDAO"/>
  45. </bean>
  46. <!-- 安全管理器 -->
  47. <bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">
  48. <property name="realms">
  49. <list><ref bean="userRealm"/></list>
  50. </property>
  51. <property name="sessionManager" ref="sessionManager"/>
  52. <property name="cacheManager" ref="cacheManager"/>
  53. </bean>
  54. <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
  55. <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
  56. <property name="staticMethod"
  57. value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
  58. <property name="arguments" ref="securityManager"/>
  59. </bean>
  60. <!-- Shiro生命周期处理器-->
  61. <bean id="lifecycleBeanPostProcessor"
  62. class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

可以看出,只要把之前的ini配置翻译为此处的spring xml配置方式即可,无须多解释。LifecycleBeanPostProcessor用于在实现了Initializable接口的Shiro bean初始化时调用Initializable接口回调,在实现了Destroyable接口的Shiro bean销毁时调用 Destroyable接口回调。如UserRealm就实现了Initializable,而DefaultSecurityManager实现了Destroyable。具体可以查看它们的继承关系。

测试用例请参考com.github.zhangkaitao.shiro.chapter12.ShiroTest。

Web应用

Web应用和普通JavaSE应用的某些配置是类似的,此处只提供一些不一样的配置,详细配置可以参考spring-shiro-web.xml。

  1. <!-- 会话Cookie模板 -->
  2. <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
  3. <constructor-arg value="sid"/>
  4. <property name="httpOnly" value="true"/>
  5. <property name="maxAge" value="180000"/>
  6. </bean>
  7. <!-- 会话管理器 -->
  8. <bean id="sessionManager"
  9. class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
  10. <property name="globalSessionTimeout" value="1800000"/>
  11. <property name="deleteInvalidSessions" value="true"/>
  12. <property name="sessionValidationSchedulerEnabled" value="true"/>
  13. <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
  14. <property name="sessionDAO" ref="sessionDAO"/>
  15. <property name="sessionIdCookieEnabled" value="true"/>
  16. <property name="sessionIdCookie" ref="sessionIdCookie"/>
  17. </bean>
  18. <!-- 安全管理器 -->
  19. <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
  20. <property name="realm" ref="userRealm"/>
  21. <property name="sessionManager" ref="sessionManager"/>
  22. <property name="cacheManager" ref="cacheManager"/>
  23. </bean>

1、sessionIdCookie是用于生产Session ID Cookie的模板;

2、会话管理器使用用于web环境的DefaultWebSessionManager;

3、安全管理器使用用于web环境的DefaultWebSecurityManager。

  1. <!-- 基于Form表单的身份验证过滤器 -->
  2. <bean id="formAuthenticationFilter"
  3. class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
  4. <property name="usernameParam" value="username"/>
  5. <property name="passwordParam" value="password"/>
  6. <property name="loginUrl" value="/login.jsp"/>
  7. </bean>
  8. <!-- Shiro的Web过滤器 -->
  9. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  10. <property name="securityManager" ref="securityManager"/>
  11. <property name="loginUrl" value="/login.jsp"/>
  12. <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
  13. <property name="filters">
  14. <util:map>
  15. <entry key="authc" value-ref="formAuthenticationFilter"/>
  16. </util:map>
  17. </property>
  18. <property name="filterChainDefinitions">
  19. <value>
  20. /index.jsp = anon
  21. /unauthorized.jsp = anon
  22. /login.jsp = authc
  23. /logout = logout
  24. /** = user
  25. </value>
  26. </property>
  27. </bean>

1、formAuthenticationFilter为基于Form表单的身份验证过滤器;此处可以再添加自己的Filter bean定义;

2、shiroFilter:此处使用ShiroFilterFactoryBean来创建ShiroFilter过滤器;filters属性用于定义自己的过滤器,即ini配置中的[filters]部分;filterChainDefinitions用于声明url和filter的关系,即ini配置中的[urls]部分。

接着需要在web.xml中进行如下配置:

  1. <context-param>
  2. <param-name>contextConfigLocation</param-name>
  3. <param-value>
  4. classpath:spring-beans.xml,
  5. classpath:spring-shiro-web.xml
  6. </param-value>
  7. </context-param>
  8. <listener>
  9. <listener-class>
  10. org.springframework.web.context.ContextLoaderListener
  11. </listener-class>
  12. </listener>

通过ContextLoaderListener加载contextConfigLocation指定的Spring配置文件。

  1. <filter>
  2. <filter-name>shiroFilter</filter-name>
  3. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  4. <init-param>
  5. <param-name>targetFilterLifecycle</param-name>
  6. <param-value>true</param-value>
  7. </init-param>
  8. </filter>
  9. <filter-mapping>
  10. <filter-name>shiroFilter</filter-name>
  11. <url-pattern>/*</url-pattern>
  12. </filter-mapping>

DelegatingFilterProxy会自动到Spring容器中查找名字为shiroFilter的bean并把filter请求交给它处理。

其他配置请参考源代码。

Shiro权限注解

Shiro提供了相应的注解用于权限控制,如果使用这些注解就需要使用AOP的功能来进行判断,如Spring AOP;Shiro提供了Spring AOP集成用于权限注解的解析和验证。

为了测试,此处使用了Spring MVC来测试Shiro注解,当然Shiro注解不仅仅可以在web环境使用,在独立的JavaSE中也是可以用的,此处只是以web为例了。

在spring-mvc.xml配置文件添加Shiro Spring AOP权限注解的支持:

  1. <aop:config proxy-target-class="true"></aop:config>
  2. <bean class="
  3. org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
  4. <property name="securityManager" ref="securityManager"/>
  5. </bean>

如上配置用于开启Shiro Spring AOP权限注解的支持;<aop:config proxy-target-class="true">表示代理类。

接着就可以在相应的控制器(AnnotationController)中使用如下方式进行注解:

  1. @RequiresRoles("admin")
  2. @RequestMapping("/hello2")
  3. public String hello2() {
  4. return "success";
  5. }

访问hello2方法的前提是当前用户有admin角色。

当验证失败,其会抛出UnauthorizedException异常,此时可以使用Spring的ExceptionHandler(DefaultExceptionHandler)来进行拦截处理:

  1. @ExceptionHandler({UnauthorizedException.class})
  2. @ResponseStatus(HttpStatus.UNAUTHORIZED)
  3. public ModelAndView processUnauthenticatedException(NativeWebRequest request, UnauthorizedException e) {
  4. ModelAndView mv = new ModelAndView();
  5. mv.addObject("exception", e);
  6. mv.setViewName("unauthorized");
  7. return mv;
  8. }

如果集成Struts2,需要注意《Shiro+Struts2+Spring3 加上@RequiresPermissions 后@Autowired失效》问题:

http://jinnianshilongnian.iteye.com/blog/1850425

权限注解

  1. @RequiresAuthentication

表示当前Subject已经通过login进行了身份验证;即Subject. isAuthenticated()返回true。

  1. @RequiresUser

表示当前Subject已经身份验证或者通过记住我登录的。

  1. @RequiresGuest

表示当前Subject没有身份验证或通过记住我登录过,即是游客身份。

  1. @RequiresRoles(value={“admin”, “user”}, logical= Logical.AND)

表示当前Subject需要角色admin和user。

  1. @RequiresPermissions (value={“user:a”, “user:b”}, logical= Logical.OR)

表示当前Subject需要权限user:a或user:b。

示例源代码:https://github.com/zhangkaitao/shiro-example;可加群 231889722 探讨Spring/Shiro技术

第十二章 与Spring集成——《跟我学Shiro》的更多相关文章

  1. 2017.2.13 开涛shiro教程-第十二章-与Spring集成(二)shiro权限注解

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十二章-与Spring集成(二)shiro权限注解 shiro注 ...

  2. 2017.2.13 开涛shiro教程-第十二章-与Spring集成(一)配置文件详解

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十二章-与Spring集成(一)配置文件详解 1.pom.xml ...

  3. 第十五章 单点登录——《跟我学Shiro》

    目录贴:跟我学Shiro目录贴 Shiro 1.2开始提供了Jasig CAS单点登录的支持,单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个 ...

  4. 十六章 综合实例——《跟我学Shiro》

    目录贴:跟我学Shiro目录贴 简单的实体关系图 简单数据字典 用户(sys_user) 名称 类型 长度 描述 id bigint 编号 主键 username varchar 100 用户名 pa ...

  5. 第十六章 综合实例——《跟我学Shiro》

    简单的实体关系图 简单数据字典 用户(sys_user) 名称 类型 长度 描述 id bigint 编号 主键 username varchar 100 用户名 password varchar 1 ...

  6. <构建之法>第十一章、十二章有感

    十一章:软件设计与实现 工作时要懂得平衡进度和质量.我一直有一个困扰:像我们团队这次做 男神女神配 社区交友网,我负责主页的设计及内容模块,有个队友负责网站的注册和登录模块,有个队友负责搜索模块,有个 ...

  7. Gradle 1.12用户指南翻译——第二十二章. 标准的 Gradle 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

  8. o'Reill的SVG精髓(第二版)学习笔记——第十二章

    第十二章 SVG动画 12.1动画基础 SVG的动画特性基于万维网联盟的“同步多媒体集成语言”(SMIL)规范(http://www.w3.org/TR/SMIL3). 在这个动画系统中,我们可以指定 ...

  9. 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探

    SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...

随机推荐

  1. 使用webuploader实现大文件传输

    这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数 下面直接贴代码吧,一些难懂的我大部分都加上注释了: 上传文件实体类: 看得 ...

  2. 块状链表 codevs 2333弹飞绵羊

    块状链表,分块处理,先预处理每一个点跳到下一个块 跳到哪,步数.然后修改的时候,修该那一个块即可 #include<cstdio>#include<cmath>int a[20 ...

  3. CSPS模拟94

    我好菜啊...... %%%迪神AK 虽然考试成绩不太好,但至少能想到正解了,也不会菜到打不出暴力. T1:想了半天不会,发现直接打高精可以拿到80分,就赶紧码完扔了,结果正解是利用double避免了 ...

  4. 快速打造自己的PHPStorm主题

    ---恢复内容开始--- 一个优雅和舒适的界面,可以增加过多写入代码的动力. Phpstorm小型的白色主题比较简陋.为了打造一个优雅和舒适的界面,我们安装一件叫Material Theme UI的插 ...

  5. BZOJ3236作业

    这东西是个应用为O(logn)的莫队. 正常莫队的updata函数转移是O(1)的,可这个题时间非常宽泛,可以套两个树状数组,那两个东西很好维护,第一个直接普通权值树状数组维护,第二个开一个桶,记录当 ...

  6. 第四章 基本TCP套接字编程 第五章 TCP客户/服务器程序实例

    TCP客户与服务器进程之间发生的重大事件时间表 TCP服务器 socket() --- bind() --- listen() --- accept() --- read() --- write -- ...

  7. 20175234 2018-2019-2 《Java程序设计》第十周学习总结

    目录 20175234 2018-2019-2 <Java程序设计>第十周学习总结 教材学习内容总结 12.1进程与线程 12.2 Java中的线程 12.3 Thread类与线程的创建 ...

  8. Selenium 常用JS

    滑动scroll: window.scrollTo(0,document.body.scrollHeight);

  9. Linux make menuconfig打开失败

    OS:Ubuntu 16.04 LTS 使用“make menuconfig”配置kernel时,提示make menuconfig打开失败 $ make menuconfig *** Unable ...

  10. Cesium的Property机制总结

    前言 Cesium官方教程中有一篇叫<空间数据可视化>(Visualizing Spatial Data).该文文末简单提到了Cesium的Property机制,然后话锋一转,宣告此教程的 ...