ShiroConfig.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. package com.ruoyi.framework.config;
  2. import java.util.LinkedHashMap;
  3. import java.util.Map;
  4. import javax.servlet.Filter;
  5. import org.apache.shiro.cache.ehcache.EhCacheManager;
  6. import org.apache.shiro.codec.Base64;
  7. import org.apache.shiro.mgt.SecurityManager;
  8. import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
  9. import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
  10. import org.apache.shiro.web.mgt.CookieRememberMeManager;
  11. import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
  12. import org.apache.shiro.web.servlet.SimpleCookie;
  13. import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
  14. import org.springframework.beans.factory.annotation.Qualifier;
  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.ruoyi.common.utils.StringUtils;
  19. import com.ruoyi.framework.shiro.realm.UserRealm;
  20. import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
  21. import com.ruoyi.framework.shiro.session.OnlineSessionFactory;
  22. import com.ruoyi.framework.shiro.web.filter.LogoutFilter;
  23. import com.ruoyi.framework.shiro.web.filter.captcha.CaptchaValidateFilter;
  24. import com.ruoyi.framework.shiro.web.filter.online.OnlineSessionFilter;
  25. import com.ruoyi.framework.shiro.web.filter.sync.SyncOnlineSessionFilter;
  26. import com.ruoyi.framework.shiro.web.session.OnlineWebSessionManager;
  27. import com.ruoyi.framework.shiro.web.session.SpringSessionValidationScheduler;
  28. import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
  29. /**
  30. * 权限配置加载
  31. *
  32. * @author ruoyi
  33. */
  34. @Configuration
  35. public class ShiroConfig
  36. {
  37. public static final String PREMISSION_STRING = "perms[\"{0}\"]";
  38. // Session超时时间,单位为毫秒(默认30分钟)
  39. @Value("${shiro.session.expireTime}")
  40. private int expireTime;
  41. // 相隔多久检查一次session的有效性,单位毫秒,默认就是10分钟
  42. @Value("${shiro.session.validationInterval}")
  43. private int validationInterval;
  44. // 验证码开关
  45. @Value("${shiro.user.captchaEbabled}")
  46. private boolean captchaEbabled;
  47. // 验证码类型
  48. @Value("${shiro.user.captchaType}")
  49. private String captchaType;
  50. // 设置Cookie的域名
  51. @Value("${shiro.cookie.domain}")
  52. private String domain;
  53. // 设置cookie的有效访问路径
  54. @Value("${shiro.cookie.path}")
  55. private String path;
  56. // 设置HttpOnly属性
  57. @Value("${shiro.cookie.httpOnly}")
  58. private boolean httpOnly;
  59. // 设置Cookie的过期时间,秒为单位
  60. @Value("${shiro.cookie.maxAge}")
  61. private int maxAge;
  62. // 登录地址
  63. @Value("${shiro.user.loginUrl}")
  64. private String loginUrl;
  65. // 权限认证失败地址
  66. @Value("${shiro.user.unauthorizedUrl}")
  67. private String unauthorizedUrl;
  68. /**
  69. * 缓存管理器 使用Ehcache实现
  70. */
  71. @Bean
  72. public EhCacheManager getEhCacheManager()
  73. {
  74. net.sf.ehcache.CacheManager cacheManager = net.sf.ehcache.CacheManager.getCacheManager("ruoyi");
  75. EhCacheManager em = new EhCacheManager();
  76. if (StringUtils.isNull(cacheManager))
  77. {
  78. em.setCacheManagerConfigFile("classpath:ehcache/ehcache-shiro.xml");
  79. return em;
  80. }
  81. else
  82. {
  83. em.setCacheManager(cacheManager);
  84. return em;
  85. }
  86. }
  87. /**
  88. * 自定义Realm
  89. */
  90. @Bean
  91. public UserRealm userRealm(EhCacheManager cacheManager)
  92. {
  93. UserRealm userRealm = new UserRealm();
  94. userRealm.setCacheManager(cacheManager);
  95. return userRealm;
  96. }
  97. /**
  98. * 自定义sessionDAO会话
  99. */
  100. @Bean
  101. public OnlineSessionDAO sessionDAO()
  102. {
  103. OnlineSessionDAO sessionDAO = new OnlineSessionDAO();
  104. return sessionDAO;
  105. }
  106. /**
  107. * 自定义sessionFactory会话
  108. */
  109. @Bean
  110. public OnlineSessionFactory sessionFactory()
  111. {
  112. OnlineSessionFactory sessionFactory = new OnlineSessionFactory();
  113. return sessionFactory;
  114. }
  115. /**
  116. * 自定义sessionFactory调度器
  117. */
  118. @Bean
  119. public SpringSessionValidationScheduler sessionValidationScheduler()
  120. {
  121. SpringSessionValidationScheduler sessionValidationScheduler = new SpringSessionValidationScheduler();
  122. // 相隔多久检查一次session的有效性,单位毫秒,默认就是10分钟
  123. sessionValidationScheduler.setSessionValidationInterval(validationInterval * 60 * 1000);
  124. // 设置会话验证调度器进行会话验证时的会话管理器
  125. sessionValidationScheduler.setSessionManager(sessionValidationManager());
  126. return sessionValidationScheduler;
  127. }
  128. /**
  129. * 会话管理器
  130. */
  131. @Bean
  132. public OnlineWebSessionManager sessionValidationManager()
  133. {
  134. OnlineWebSessionManager manager = new OnlineWebSessionManager();
  135. // 加入缓存管理器
  136. manager.setCacheManager(getEhCacheManager());
  137. // 删除过期的session
  138. manager.setDeleteInvalidSessions(true);
  139. // 设置全局session超时时间
  140. manager.setGlobalSessionTimeout(expireTime * 60 * 1000);
  141. // 去掉 JSESSIONID
  142. manager.setSessionIdUrlRewritingEnabled(false);
  143. // 是否定时检查session
  144. manager.setSessionValidationSchedulerEnabled(true);
  145. // 自定义SessionDao
  146. manager.setSessionDAO(sessionDAO());
  147. // 自定义sessionFactory
  148. manager.setSessionFactory(sessionFactory());
  149. return manager;
  150. }
  151. /**
  152. * 会话管理器
  153. */
  154. @Bean
  155. public OnlineWebSessionManager sessionManager()
  156. {
  157. OnlineWebSessionManager manager = new OnlineWebSessionManager();
  158. // 加入缓存管理器
  159. manager.setCacheManager(getEhCacheManager());
  160. // 删除过期的session
  161. manager.setDeleteInvalidSessions(true);
  162. // 设置全局session超时时间
  163. manager.setGlobalSessionTimeout(expireTime * 60 * 1000);
  164. // 去掉 JSESSIONID
  165. manager.setSessionIdUrlRewritingEnabled(false);
  166. // 定义要使用的无效的Session定时调度器
  167. manager.setSessionValidationScheduler(sessionValidationScheduler());
  168. // 是否定时检查session
  169. manager.setSessionValidationSchedulerEnabled(true);
  170. // 自定义SessionDao
  171. manager.setSessionDAO(sessionDAO());
  172. // 自定义sessionFactory
  173. manager.setSessionFactory(sessionFactory());
  174. return manager;
  175. }
  176. /**
  177. * 安全管理器
  178. */
  179. @Bean
  180. public SecurityManager securityManager(UserRealm userRealm)
  181. {
  182. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
  183. // 设置realm.
  184. securityManager.setRealm(userRealm);
  185. // 记住我
  186. securityManager.setRememberMeManager(rememberMeManager());
  187. // 注入缓存管理器;
  188. securityManager.setCacheManager(getEhCacheManager());
  189. // session管理器
  190. securityManager.setSessionManager(sessionManager());
  191. return securityManager;
  192. }
  193. /**
  194. * 退出过滤器
  195. */
  196. public LogoutFilter logoutFilter()
  197. {
  198. LogoutFilter logoutFilter = new LogoutFilter();
  199. logoutFilter.setLoginUrl(loginUrl);
  200. return logoutFilter;
  201. }
  202. /**
  203. * Shiro过滤器配置
  204. */
  205. @Bean
  206. public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager)
  207. {
  208. ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
  209. // Shiro的核心安全接口,这个属性是必须的
  210. shiroFilterFactoryBean.setSecurityManager(securityManager);
  211. // 身份认证失败,则跳转到登录页面的配置
  212. shiroFilterFactoryBean.setLoginUrl(loginUrl);
  213. // 权限认证失败,则跳转到指定页面
  214. shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);
  215. // Shiro连接约束配置,即过滤链的定义
  216. LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
  217. // 对静态资源设置匿名访问
  218. filterChainDefinitionMap.put("/favicon.ico**", "anon");
  219. filterChainDefinitionMap.put("/ruoyi.png**", "anon");
  220. filterChainDefinitionMap.put("/css/**", "anon");
  221. filterChainDefinitionMap.put("/docs/**", "anon");
  222. filterChainDefinitionMap.put("/fonts/**", "anon");
  223. filterChainDefinitionMap.put("/img/**", "anon");
  224. filterChainDefinitionMap.put("/ajax/**", "anon");
  225. filterChainDefinitionMap.put("/js/**", "anon");
  226. filterChainDefinitionMap.put("/ruoyi/**", "anon");
  227. filterChainDefinitionMap.put("/druid/**", "anon");
  228. filterChainDefinitionMap.put("/captcha/captchaImage**", "anon");
  229. // 退出 logout地址,shiro去清除session
  230. filterChainDefinitionMap.put("/logout", "logout");
  231. // 不需要拦截的访问
  232. filterChainDefinitionMap.put("/login", "anon,captchaValidate");
  233. // 系统权限列表
  234. // filterChainDefinitionMap.putAll(SpringUtils.getBean(IMenuService.class).selectPermsAll());
  235. Map<String, Filter> filters = new LinkedHashMap<>();
  236. filters.put("onlineSession", onlineSessionFilter());
  237. filters.put("syncOnlineSession", syncOnlineSessionFilter());
  238. filters.put("captchaValidate", captchaValidateFilter());
  239. // 注销成功,则跳转到指定页面
  240. filters.put("logout", logoutFilter());
  241. shiroFilterFactoryBean.setFilters(filters);
  242. // 所有请求需要认证
  243. filterChainDefinitionMap.put("/**", "user");
  244. // 系统请求记录当前会话
  245. filterChainDefinitionMap.put("/main", "onlineSession,syncOnlineSession");
  246. filterChainDefinitionMap.put("/system/**", "onlineSession,syncOnlineSession");
  247. filterChainDefinitionMap.put("/monitor/**", "onlineSession,syncOnlineSession");
  248. filterChainDefinitionMap.put("/tool/**", "onlineSession,syncOnlineSession");
  249. shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
  250. return shiroFilterFactoryBean;
  251. }
  252. /**
  253. * 自定义在线用户处理过滤器
  254. */
  255. @Bean
  256. public OnlineSessionFilter onlineSessionFilter()
  257. {
  258. OnlineSessionFilter onlineSessionFilter = new OnlineSessionFilter();
  259. onlineSessionFilter.setLoginUrl(loginUrl);
  260. return onlineSessionFilter;
  261. }
  262. /**
  263. * 自定义在线用户同步过滤器
  264. */
  265. @Bean
  266. public SyncOnlineSessionFilter syncOnlineSessionFilter()
  267. {
  268. SyncOnlineSessionFilter syncOnlineSessionFilter = new SyncOnlineSessionFilter();
  269. return syncOnlineSessionFilter;
  270. }
  271. /**
  272. * 自定义验证码过滤器
  273. */
  274. @Bean
  275. public CaptchaValidateFilter captchaValidateFilter()
  276. {
  277. CaptchaValidateFilter captchaValidateFilter = new CaptchaValidateFilter();
  278. captchaValidateFilter.setCaptchaEbabled(captchaEbabled);
  279. captchaValidateFilter.setCaptchaType(captchaType);
  280. return captchaValidateFilter;
  281. }
  282. /**
  283. * cookie 属性设置
  284. */
  285. public SimpleCookie rememberMeCookie()
  286. {
  287. SimpleCookie cookie = new SimpleCookie("rememberMe");
  288. cookie.setDomain(domain);
  289. cookie.setPath(path);
  290. cookie.setHttpOnly(httpOnly);
  291. cookie.setMaxAge(maxAge * 24 * 60 * 60);
  292. return cookie;
  293. }
  294. /**
  295. * 记住我
  296. */
  297. public CookieRememberMeManager rememberMeManager()
  298. {
  299. CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
  300. cookieRememberMeManager.setCookie(rememberMeCookie());
  301. cookieRememberMeManager.setCipherKey(Base64.decode("fCq+/xW488hMTCD+cmJ3aQ=="));
  302. return cookieRememberMeManager;
  303. }
  304. /**
  305. * 开启Shiro代理
  306. */
  307. @Bean
  308. public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator()
  309. {
  310. DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
  311. proxyCreator.setProxyTargetClass(true);
  312. return proxyCreator;
  313. }
  314. /**
  315. * thymeleaf模板引擎和shiro框架的整合
  316. */
  317. @Bean
  318. public ShiroDialect shiroDialect()
  319. {
  320. return new ShiroDialect();
  321. }
  322. /**
  323. * 开启Shiro注解通知器
  324. */
  325. @Bean
  326. public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
  327. @Qualifier("securityManager") SecurityManager securityManager)
  328. {
  329. AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
  330. authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
  331. return authorizationAttributeSourceAdvisor;
  332. }
  333. }