ShiroConfig.kt 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. package com.gxzc.zen.umps.config
  2. import com.gxzc.zen.umps.constant.ZenHttpSession
  3. import com.gxzc.zen.umps.filter.AjaxAuthorizationFilter
  4. import com.gxzc.zen.umps.filter.UrlPermissionsFilter
  5. import com.gxzc.zen.umps.filter.ZenCorsAnonymousFilter
  6. import com.gxzc.zen.umps.filter.ZenCorsPathMatchingFilter
  7. import org.apache.shiro.authc.credential.HashedCredentialsMatcher
  8. import org.apache.shiro.spring.LifecycleBeanPostProcessor
  9. import org.apache.shiro.spring.web.ShiroFilterFactoryBean
  10. import org.apache.shiro.web.filter.authc.AnonymousFilter
  11. import org.apache.shiro.web.mgt.DefaultWebSecurityManager
  12. import org.apache.shiro.web.servlet.SimpleCookie
  13. import org.springframework.boot.context.properties.ConfigurationProperties
  14. import org.springframework.boot.web.servlet.FilterRegistrationBean
  15. import org.springframework.context.annotation.Bean
  16. import org.springframework.context.annotation.Configuration
  17. import org.springframework.context.annotation.DependsOn
  18. import org.springframework.core.annotation.Order
  19. import org.springframework.data.redis.connection.jedis.JedisConnectionFactory
  20. import org.springframework.data.redis.core.RedisTemplate
  21. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
  22. import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
  23. import org.springframework.data.redis.serializer.StringRedisSerializer
  24. import org.springframework.web.filter.DelegatingFilterProxy
  25. import javax.servlet.DispatcherType
  26. import javax.servlet.Filter
  27. /**
  28. * Shiro配置
  29. * @author NorthLan
  30. * @date 2018/4/21
  31. * @url https://noahlan.com
  32. */
  33. @Configuration
  34. class ShiroConfig {
  35. @Bean
  36. @ConfigurationProperties(prefix = "shiro.redis")
  37. fun shiroRedisProperties(): ShiroRedisProperties {
  38. return ShiroRedisProperties()
  39. }
  40. @Bean("shiroFilterRegistrationBean")
  41. @DependsOn("shiroFilter")
  42. fun filterRegistrationBean(): FilterRegistrationBean {
  43. return FilterRegistrationBean().apply {
  44. filter = DelegatingFilterProxy("shiroFilter")
  45. isEnabled = true
  46. addUrlPatterns("/*")
  47. setDispatcherTypes(DispatcherType.REQUEST)
  48. }
  49. }
  50. @Bean(name = ["shiroFilter"])
  51. @Order(2)
  52. fun shiroFilter(): ShiroFilterFactoryBean {
  53. return ShiroFilterFactoryBean().apply {
  54. securityManager = securityManager()
  55. // loginUrl = "/login"
  56. // unauthorizedUrl = "/unauthor"
  57. filters = hashMapOf<String, Filter>(
  58. "canon" to ZenCorsAnonymousFilter(),
  59. "cors" to ZenCorsPathMatchingFilter(),
  60. "perms" to UrlPermissionsFilter(),
  61. "authc" to AjaxAuthorizationFilter(),
  62. "anon" to AnonymousFilter()
  63. )
  64. /**
  65. * anon(匿名) org.apache.shiro.web.filter.authc.AnonymousFilter
  66. * authc(身份验证) org.apache.shiro.web.filter.authc.FormAuthenticationFilter
  67. * authcBasic(http基本验证) org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
  68. * logout(退出) org.apache.shiro.web.filter.authc.LogoutFilter
  69. * noSessionCreation(不创建session) org.apache.shiro.web.filter.session.NoSessionCreationFilter
  70. * perms(许可验证) org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
  71. * port(端口验证) org.apache.shiro.web.filter.authz.PortFilter
  72. * rest (rest方面) org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
  73. * roles(权限验证) org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
  74. * ssl (ssl方面) org.apache.shiro.web.filter.authz.SslFilter
  75. * member (用户方面) org.apache.shiro.web.filter.authc.UserFilter
  76. * user 表示用户不一定已通过认证,只要曾被Shiro记住过登录状态的用户就可以正常发起请求,比如rememberMe
  77. */
  78. filterChainDefinitionMap = linkedMapOf<String, String>( // BUG 此处一定要使用 linkedHashMap 否则顺序有问题
  79. "/auth/setcookie" to "canon", // 设置cookie
  80. "/auth/check" to "canon", // 检查登录状态
  81. // "/auth/logout" to "logout", // 登出
  82. "/test/**" to "canon", // 测试 免登录
  83. "/upload/**" to "canon", // 上传免登录
  84. "/api/**" to "canon", // api 免登陆
  85. ////////////////////// 静态资源 /////////////////////
  86. "/v2/api-docs" to "canon",
  87. "/swagger-resources/**" to "anon",
  88. "/swagger-ui.html" to "anon",
  89. "/webjars*" to "anon",
  90. "/webjars/**" to "anon",
  91. "/druid/**" to "anon",
  92. "/druid/sql.json" to "anon",
  93. "/**/favicon.*" to "anon",
  94. ////////////////////// 静态资源 /////////////////////
  95. "/**" to "cors,authc,perms" // 对于其他未配置的所有url 先设置cors头 再进行登陆判定 最后判定权限
  96. )
  97. }
  98. }
  99. @Bean(name = ["securityManager"])
  100. fun securityManager(): DefaultWebSecurityManager {
  101. return DefaultWebSecurityManager().apply {
  102. setRealm(userRealm())
  103. cacheManager = redisCacheManager()
  104. sessionManager = defaultWebSessionManager()
  105. }
  106. }
  107. @Bean(name = ["sessionManager"])
  108. fun defaultWebSessionManager(): ZenWebSessionManager {
  109. return ZenWebSessionManager().apply {
  110. setCacheManager(redisCacheManager())
  111. globalSessionTimeout = 604800 * 1000
  112. isDeleteInvalidSessions = true
  113. isSessionValidationSchedulerEnabled = true
  114. isDeleteInvalidSessions = true
  115. sessionDAO = redisSessionDAO()
  116. sessionIdCookie = SimpleCookie(ZenHttpSession.DEFAULT_SESSION_ID_NAME).apply {
  117. isHttpOnly = true
  118. maxAge = 604800
  119. }
  120. }
  121. }
  122. @Bean
  123. fun redisSessionDAO(): ShiroRedisSessionDAO {
  124. return ShiroRedisSessionDAO(redisTemplate(), shiroRedisProperties())
  125. }
  126. @Bean
  127. @DependsOn(value = ["shiroLifecycleBeanPostProcessor", "shrioRedisCacheManager"])
  128. fun userRealm(): ZenShiroRealm {
  129. return ZenShiroRealm().apply {
  130. cacheManager = redisCacheManager()
  131. isCachingEnabled = true
  132. isAuthenticationCachingEnabled = true
  133. isAuthorizationCachingEnabled = true
  134. //TODO 以下 hash 验证,后期的重试 ban 可重写此类实现
  135. credentialsMatcher = HashedCredentialsMatcher().also {
  136. it.hashAlgorithmName = "md5"
  137. it.hashIterations = 2 // 两次md5
  138. }
  139. }
  140. }
  141. @Bean(name = ["shrioRedisCacheManager"])
  142. @DependsOn(value = ["shiroRedisTemplate"])
  143. fun redisCacheManager(): ShiroRedisCacheManager {
  144. return ShiroRedisCacheManager(redisTemplate(), shiroRedisProperties())
  145. }
  146. @Bean(name = ["shiroRedisTemplate"])
  147. fun redisTemplate(): RedisTemplate<String, Any> {
  148. return RedisTemplate<String, Any>().apply {
  149. connectionFactory = connectionFactory()
  150. val stringSerializer = StringRedisSerializer()
  151. keySerializer = stringSerializer
  152. valueSerializer = JdkSerializationRedisSerializer()
  153. hashKeySerializer = stringSerializer
  154. hashValueSerializer = Jackson2JsonRedisSerializer(Any::class.java)
  155. }
  156. }
  157. @Bean("shiroRedisConnectionFactory")
  158. fun connectionFactory(): JedisConnectionFactory {
  159. val properties = shiroRedisProperties()
  160. return JedisConnectionFactory().apply {
  161. database = properties.database
  162. hostName = properties.host
  163. password = properties.password
  164. port = properties.port
  165. timeout = properties.timeout
  166. }
  167. }
  168. @Bean("shiroLifecycleBeanPostProcessor")
  169. fun lifecycleBeanPostProcessor(): LifecycleBeanPostProcessor {
  170. return LifecycleBeanPostProcessor()
  171. }
  172. }