Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 

211 строки
7.5 KiB

  1. package com.simple.config;
  2. import java.util.LinkedHashMap;
  3. import java.util.Map;
  4. import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
  5. import org.apache.shiro.mgt.SecurityManager;
  6. import org.apache.shiro.spring.LifecycleBeanPostProcessor;
  7. import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
  8. import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
  9. import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
  10. import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
  11. import org.crazycake.shiro.RedisCacheManager;
  12. import org.crazycake.shiro.RedisManager;
  13. import org.crazycake.shiro.RedisSessionDAO;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.beans.factory.annotation.Value;
  16. import org.springframework.context.annotation.Bean;
  17. import org.springframework.context.annotation.Configuration;
  18. import com.simple.service.SysPermissionService;
  19. import com.simple.shiro.MyShiroRealm;
  20. /**
  21. * Created by yangqj on 2017/4/23.
  22. */
  23. @Configuration
  24. public class ShiroConfig {
  25. @Autowired(required = false)
  26. private SysPermissionService resourcesService;
  27. @Value("${spring.redis.host}")
  28. private String host;
  29. @Value("${spring.redis.port}")
  30. private int port;
  31. @Value("${spring.redis.timeout}")
  32. private int timeout;
  33. @Value("${spring.redis.expire}")
  34. private int expire;
  35. @Bean
  36. public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
  37. return new LifecycleBeanPostProcessor();
  38. }
  39. /**
  40. * ShiroDialect,为了在thymeleaf里使用shiro的标签的bean
  41. * @return
  42. */
  43. // @Bean
  44. // public ShiroDialect shiroDialect() {
  45. // return new ShiroDialect();
  46. // }
  47. /**
  48. * ShiroFilterFactoryBean 处理拦截资源文件问题。
  49. * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,因为在
  50. * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
  51. *
  52. Filter Chain定义说明
  53. 1、一个URL可以配置多个Filter,使用逗号分隔
  54. 2、当设置多个过滤器时,全部验证通过,才视为通过
  55. 3、部分过滤器可指定参数,如perms,roles
  56. *
  57. */
  58. @Bean
  59. public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){
  60. System.out.println("ShiroConfiguration.shirFilter()");
  61. ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
  62. // 必须设置 SecurityManager
  63. shiroFilterFactoryBean.setSecurityManager(securityManager);
  64. // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
  65. shiroFilterFactoryBean.setLoginUrl("/login");
  66. // 登录成功后要跳转的链接
  67. shiroFilterFactoryBean.setSuccessUrl("/usersPage");
  68. //未授权界面;
  69. shiroFilterFactoryBean.setUnauthorizedUrl("/403");
  70. //拦截器.
  71. Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
  72. //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
  73. filterChainDefinitionMap.put("/logout", "logout");
  74. filterChainDefinitionMap.put("/doLogin/**","anon");
  75. filterChainDefinitionMap.put("/css/**","anon");
  76. filterChainDefinitionMap.put("/js/**","anon");
  77. filterChainDefinitionMap.put("/img/**","anon");
  78. filterChainDefinitionMap.put("/font-awesome/**","anon");
  79. //<!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
  80. //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
  81. //自定义加载权限资源关系
  82. // Map<String,Object> map = new HashMap<>();
  83. // List<SysPermission> resourcesList = resourcesService.list(map);
  84. // for(SysPermission resources:resourcesList){
  85. //
  86. // if (StringUtil.isNotEmpty(resources.getUrl())) {
  87. // String permission = "perms[" + resources.getUrl()+ "]";
  88. // filterChainDefinitionMap.put(resources.getUrl(),permission);
  89. // }
  90. // }
  91. filterChainDefinitionMap.put("/**", "authc");
  92. shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
  93. return shiroFilterFactoryBean;
  94. }
  95. @Bean
  96. public SecurityManager securityManager(){
  97. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
  98. //设置realm.
  99. securityManager.setRealm(myShiroRealm());
  100. // 自定义缓存实现 使用redis
  101. //securityManager.setCacheManager(cacheManager());
  102. // 自定义session管理 使用redis
  103. securityManager.setSessionManager(sessionManager());
  104. return securityManager;
  105. }
  106. @Bean
  107. public MyShiroRealm myShiroRealm(){
  108. MyShiroRealm myShiroRealm = new MyShiroRealm();
  109. myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
  110. return myShiroRealm;
  111. }
  112. /**
  113. * 凭证匹配器
  114. * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
  115. * 所以我们需要修改下doGetAuthenticationInfo中的代码;
  116. * )
  117. * @return
  118. */
  119. @Bean
  120. public HashedCredentialsMatcher hashedCredentialsMatcher(){
  121. HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
  122. hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
  123. hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
  124. return hashedCredentialsMatcher;
  125. }
  126. /**
  127. * 开启shiro aop注解支持.
  128. * 使用代理方式;所以需要开启代码支持;
  129. * @param securityManager
  130. * @return
  131. */
  132. @Bean
  133. public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
  134. AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
  135. authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
  136. return authorizationAttributeSourceAdvisor;
  137. }
  138. /**
  139. * 配置shiro redisManager
  140. * 使用的是shiro-redis开源插件
  141. * @return
  142. */
  143. public RedisManager redisManager() {
  144. RedisManager redisManager = new RedisManager();
  145. redisManager.setHost(host);
  146. redisManager.setPort(port);
  147. redisManager.setExpire(expire);// 配置缓存过期时间
  148. redisManager.setTimeout(timeout);
  149. // redisManager.setPassword(password);
  150. return redisManager;
  151. }
  152. /**
  153. * cacheManager 缓存 redis实现
  154. * 使用的是shiro-redis开源插件
  155. * @return
  156. */
  157. public RedisCacheManager cacheManager() {
  158. RedisCacheManager redisCacheManager = new RedisCacheManager();
  159. redisCacheManager.setRedisManager(redisManager());
  160. return redisCacheManager;
  161. }
  162. /**
  163. * RedisSessionDAO shiro sessionDao层的实现 通过redis
  164. * 使用的是shiro-redis开源插件
  165. */
  166. @Bean
  167. public RedisSessionDAO redisSessionDAO() {
  168. RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
  169. redisSessionDAO.setRedisManager(redisManager());
  170. return redisSessionDAO;
  171. }
  172. /**
  173. * shiro session的管理
  174. */
  175. @Bean
  176. public DefaultWebSessionManager sessionManager() {
  177. DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
  178. sessionManager.setSessionDAO(redisSessionDAO());
  179. return sessionManager;
  180. }
  181. }