You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

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