ShiroConfig.kt 7.6 KB

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