123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- package com.gxzc.zen.umps.config
- import com.gxzc.zen.umps.constant.ZenHttpSession
- import com.gxzc.zen.umps.filter.AjaxAuthorizationFilter
- import com.gxzc.zen.umps.filter.UrlPermissionsFilter
- import com.gxzc.zen.umps.filter.ZenCorsAnonymousFilter
- import com.gxzc.zen.umps.filter.ZenCorsPathMatchingFilter
- import org.apache.shiro.authc.credential.HashedCredentialsMatcher
- import org.apache.shiro.spring.LifecycleBeanPostProcessor
- import org.apache.shiro.spring.web.ShiroFilterFactoryBean
- import org.apache.shiro.web.filter.authc.AnonymousFilter
- import org.apache.shiro.web.mgt.DefaultWebSecurityManager
- import org.apache.shiro.web.servlet.SimpleCookie
- import org.springframework.boot.context.properties.ConfigurationProperties
- import org.springframework.boot.web.servlet.FilterRegistrationBean
- import org.springframework.context.annotation.Bean
- import org.springframework.context.annotation.Configuration
- import org.springframework.context.annotation.DependsOn
- import org.springframework.core.annotation.Order
- import org.springframework.data.redis.connection.jedis.JedisConnectionFactory
- import org.springframework.data.redis.core.RedisTemplate
- import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
- import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
- import org.springframework.data.redis.serializer.StringRedisSerializer
- import org.springframework.web.filter.DelegatingFilterProxy
- import javax.servlet.DispatcherType
- import javax.servlet.Filter
- /**
- * Shiro配置
- * @author NorthLan
- * @date 2018/4/21
- * @url https://noahlan.com
- */
- @Configuration
- class ShiroConfig {
- @Bean
- @ConfigurationProperties(prefix = "shiro.redis")
- fun shiroRedisProperties(): ShiroRedisProperties {
- return ShiroRedisProperties()
- }
- @Bean("shiroFilterRegistrationBean")
- @DependsOn("shiroFilter")
- fun filterRegistrationBean(): FilterRegistrationBean<DelegatingFilterProxy> {
- return FilterRegistrationBean<DelegatingFilterProxy>().apply {
- filter = DelegatingFilterProxy("shiroFilter")
- isEnabled = true
- addUrlPatterns("/*")
- setDispatcherTypes(DispatcherType.REQUEST)
- }
- }
- @Bean(name = ["shiroFilter"])
- @Order(2)
- fun shiroFilter(): ShiroFilterFactoryBean {
- return ShiroFilterFactoryBean().apply {
- securityManager = securityManager()
- // loginUrl = "/login"
- // unauthorizedUrl = "/unauthor"
- filters = hashMapOf<String, Filter>(
- "canon" to ZenCorsAnonymousFilter(),
- "cors" to ZenCorsPathMatchingFilter(),
- "perms" to UrlPermissionsFilter(),
- "authc" to AjaxAuthorizationFilter(),
- "anon" to AnonymousFilter()
- )
- /**
- * anon(匿名) org.apache.shiro.web.filter.authc.AnonymousFilter
- * authc(身份验证) org.apache.shiro.web.filter.authc.FormAuthenticationFilter
- * authcBasic(http基本验证) org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
- * logout(退出) org.apache.shiro.web.filter.authc.LogoutFilter
- * noSessionCreation(不创建session) org.apache.shiro.web.filter.session.NoSessionCreationFilter
- * perms(许可验证) org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
- * port(端口验证) org.apache.shiro.web.filter.authz.PortFilter
- * rest (rest方面) org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
- * roles(权限验证) org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
- * ssl (ssl方面) org.apache.shiro.web.filter.authz.SslFilter
- * member (用户方面) org.apache.shiro.web.filter.authc.UserFilter
- * user 表示用户不一定已通过认证,只要曾被Shiro记住过登录状态的用户就可以正常发起请求,比如rememberMe
- */
- filterChainDefinitionMap = linkedMapOf<String, String>( // BUG 此处一定要使用 linkedHashMap 否则顺序有问题
- "/auth/setcookie" to "canon", // 设置cookie
- "/auth/check" to "canon", // 检查登录状态
- "/auth/logout" to "canon", // 登出
- "/test/**" to "canon", // 测试 免登录
- "/upload/**" to "canon", // 上传免登录
- "/fdfsupload/**" to "canon", // 上传免登录
- "/api/**" to "canon", // api 免登陆
- "/ws/**" to "canon", // websocket 免登陆
- "/" to "canon",
- ////////////////////// 静态资源 /////////////////////
- "/v2/api-docs" to "canon",
- "/swagger-resources/**" to "anon",
- "/swagger-ui.html" to "anon",
- "/webjars*" to "anon",
- "/webjars/**" to "anon",
- "/druid/**" to "anon",
- "/druid/sql.json" to "anon",
- "/**/favicon.*" to "anon",
- "/eureka/**" to "anon",
- ////////////////////// 静态资源 /////////////////////
- "/**" to "cors,authc,perms" // 对于其他未配置的所有url 先设置cors头 再进行登陆判定 最后判定权限
- )
- }
- }
- @Bean(name = ["securityManager"])
- fun securityManager(): DefaultWebSecurityManager {
- return DefaultWebSecurityManager().apply {
- setRealm(userRealm())
- cacheManager = redisCacheManager()
- sessionManager = defaultWebSessionManager()
- }
- }
- @Bean(name = ["sessionManager"])
- fun defaultWebSessionManager(): ZenWebSessionManager {
- return ZenWebSessionManager().apply {
- setCacheManager(redisCacheManager())
- globalSessionTimeout = 604800 * 1000
- isDeleteInvalidSessions = true
- isSessionValidationSchedulerEnabled = true
- isDeleteInvalidSessions = true
- sessionDAO = redisSessionDAO()
- sessionIdCookie = SimpleCookie(ZenHttpSession.DEFAULT_SESSION_ID_NAME).apply {
- isHttpOnly = true
- maxAge = 604800
- }
- }
- }
- @Bean
- fun redisSessionDAO(): ShiroRedisSessionDAO {
- return ShiroRedisSessionDAO(redisTemplate(), shiroRedisProperties())
- }
- @Bean
- @DependsOn(value = ["shiroLifecycleBeanPostProcessor", "shrioRedisCacheManager"])
- fun userRealm(): ZenShiroRealm {
- return ZenShiroRealm().apply {
- cacheManager = redisCacheManager()
- isCachingEnabled = true
- isAuthenticationCachingEnabled = true
- isAuthorizationCachingEnabled = true
- //TODO 以下 hash 验证,后期的重试 ban 可重写此类实现
- credentialsMatcher = HashedCredentialsMatcher().also {
- it.hashAlgorithmName = "md5"
- it.hashIterations = 2 // 两次md5
- }
- }
- }
- @Bean(name = ["shrioRedisCacheManager"])
- @DependsOn(value = ["shiroRedisTemplate"])
- fun redisCacheManager(): ShiroRedisCacheManager {
- return ShiroRedisCacheManager(redisTemplate(), shiroRedisProperties())
- }
- @Bean(name = ["shiroRedisTemplate"])
- fun redisTemplate(): RedisTemplate<String, Any> {
- return RedisTemplate<String, Any>().apply {
- connectionFactory = connectionFactory()
- val stringSerializer = StringRedisSerializer()
- keySerializer = stringSerializer
- valueSerializer = JdkSerializationRedisSerializer()
- hashKeySerializer = stringSerializer
- hashValueSerializer = Jackson2JsonRedisSerializer(Any::class.java)
- }
- }
- @Bean("shiroRedisConnectionFactory")
- fun connectionFactory(): JedisConnectionFactory {
- val properties = shiroRedisProperties()
- return JedisConnectionFactory().apply {
- database = properties.database
- hostName = properties.host
- password = properties.password
- port = properties.port
- timeout = properties.timeout
- }
- }
- @Bean("shiroLifecycleBeanPostProcessor")
- fun lifecycleBeanPostProcessor(): LifecycleBeanPostProcessor {
- return LifecycleBeanPostProcessor()
- }
- }
|