ShiroConfig.java 13 KB

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