mirror of
https://github.moeyy.xyz/https://github.com/GeWuYou/forgeboot
synced 2025-10-27 19:12:10 +08:00
feat(security): 实现双 token 认证机制并优化安全配置
- 在 SecurityAuthenticateProperties 中添加双 token 认证相关配置- 新增 DualTokenAuthenticationService接口和实现类,支持双 token 认证 - 添加 DualTokenAuthenticationController 实现双 token认证控制器 - 重构 SecurityAuthenticateAutoConfiguration,拆分为多个更细粒度的配置类 - 新增 SecurityCoreAutoConfiguration,集中处理安全核心配置 - 添加 SecurityProviderAutoConfiguration,自动配置认证提供者 - 新增 SecurityStrategyAutoConfiguration,自动配置安全策略 - 更新 UsernamePasswordAuthenticationProvider,支持多用户详情服务
This commit is contained in:
parent
3eb5ba6239
commit
b9da8bf395
@ -28,6 +28,7 @@ class SecurityAuthenticateProperties {
|
|||||||
* 默认认证失败响应内容,当认证失败时返回此字符串
|
* 默认认证失败响应内容,当认证失败时返回此字符串
|
||||||
*/
|
*/
|
||||||
var defaultAuthenticationFailureResponse = "If the authentication fails, please report the request ID for more information!"
|
var defaultAuthenticationFailureResponse = "If the authentication fails, please report the request ID for more information!"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 认证模块的基础URL前缀
|
* 认证模块的基础URL前缀
|
||||||
*/
|
*/
|
||||||
@ -42,4 +43,33 @@ class SecurityAuthenticateProperties {
|
|||||||
* 登出接口的URL路径
|
* 登出接口的URL路径
|
||||||
*/
|
*/
|
||||||
var logoutUrl = "/logout"
|
var logoutUrl = "/logout"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用单 token 登录认证(如登录接口、token 生成器)
|
||||||
|
*/
|
||||||
|
var singleToken: SingleTokenAuthenticationProperties = SingleTokenAuthenticationProperties()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置单 Token 认证相关属性
|
||||||
|
*
|
||||||
|
* 提供一个嵌套类来管理单 Token 认证的启用状态,这种设计模式允许在不改变主配置类的情况下,
|
||||||
|
* 独立扩展单 Token 相关的更多配置项。
|
||||||
|
*/
|
||||||
|
class SingleTokenAuthenticationProperties {
|
||||||
|
var enabled: Boolean = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用双 token 登录认证
|
||||||
|
*/
|
||||||
|
var dualToken: DualTokenAuthenticationProperties = DualTokenAuthenticationProperties()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置双 Token 认证相关属性
|
||||||
|
*
|
||||||
|
* 嵌套类用于封装双 Token 认证机制的启用状态,保持配置结构清晰并支持未来扩展。
|
||||||
|
*/
|
||||||
|
class DualTokenAuthenticationProperties {
|
||||||
|
var enabled: Boolean = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authenticate.api.customizer
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口用于支持登录过滤器扩展器的排序功能。
|
||||||
|
*
|
||||||
|
* 此接口继承自 [LoginFilterCustomizer],通过提供一个 order 属性来定义实现类的执行顺序,
|
||||||
|
* 确保多个 [LoginFilterCustomizer] 实现类能够按照预期的顺序被调用。
|
||||||
|
*
|
||||||
|
* @since 2025-06-27 07:58:46
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
interface OrderedLoginFilterCustomizer : LoginFilterCustomizer {
|
||||||
|
/**
|
||||||
|
* 定义当前定制器的执行顺序。
|
||||||
|
*
|
||||||
|
* 数值越小,优先级越高,即会越早被执行。
|
||||||
|
*/
|
||||||
|
val order: Int
|
||||||
|
}
|
||||||
@ -5,43 +5,26 @@ import com.gewuyou.forgeboot.security.core.authenticate.entities.request.LoginRe
|
|||||||
/**
|
/**
|
||||||
* 登录请求类型注册表
|
* 登录请求类型注册表
|
||||||
*
|
*
|
||||||
* 用于管理不同登录类型的请求类映射关系,支持动态注册和获取登录请求类型。
|
* 用于管理不同登录类型的请求类,支持注册和查询操作。
|
||||||
*
|
*
|
||||||
* ```kt
|
* @since 2025-06-26 22:06:00
|
||||||
* @Bean
|
|
||||||
* fun loginRequestTypeRegistry(): LoginRequestTypeRegistry {
|
|
||||||
* return LoginRequestTypeRegistry().apply {
|
|
||||||
* register("default", DefaultLoginRequest::class.java)
|
|
||||||
* register("sms", SmsLoginRequest::class.java)
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* @since 2025-06-10 16:33:43
|
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
class LoginRequestTypeRegistry {
|
interface LoginRequestTypeRegistry {
|
||||||
/**
|
|
||||||
* 内部使用可变Map保存登录类型与对应LoginRequest子类的映射关系
|
|
||||||
*/
|
|
||||||
private val mapping = mutableMapOf<String, Class<out LoginRequest>>()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册指定登录类型对应的请求类
|
* 注册一个新的登录类型及其对应的请求类。
|
||||||
*
|
*
|
||||||
* @param loginType 登录类型的标识字符串
|
* @param loginType 登录类型的标识字符串
|
||||||
* @param clazz 继承自LoginRequest的具体请求类
|
* @param clazz 继承自LoginRequest的具体请求类
|
||||||
*/
|
*/
|
||||||
fun register(loginType: String, clazz: Class<out LoginRequest>) {
|
fun register(loginType: String, clazz: Class<out LoginRequest>): LoginRequestTypeRegistry
|
||||||
mapping[loginType] = clazz
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据登录类型获取对应的请求类
|
* 根据登录类型获取对应的请求类。
|
||||||
*
|
*
|
||||||
* @param loginType 登录类型的标识字符串
|
* @param loginType 登录类型的标识字符串
|
||||||
* @return 返回对应的LoginRequest子类,若未找到则返回null
|
* @return 返回与登录类型关联的请求类,如果未找到则返回null
|
||||||
*/
|
*/
|
||||||
fun getTypeForLoginType(loginType: String): Class<out LoginRequest>? {
|
fun getTypeForLoginType(loginType: String): Class<out LoginRequest>?
|
||||||
return mapping[loginType]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authenticate.api.service
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.entities.TokenPair
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 双令牌认证服务
|
||||||
|
*
|
||||||
|
* 提供基于访问令牌和刷新令牌的认证机制相关功能接口,包含令牌生成与刷新逻辑。
|
||||||
|
*
|
||||||
|
* @since 2025-06-26 20:43:14
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
interface DualTokenAuthenticationService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新令牌并生成新的一对令牌
|
||||||
|
*
|
||||||
|
* 使用旧访问令牌(可能已过期)和有效刷新令牌生成新的 TokenPair。
|
||||||
|
* 刷新过程中会验证刷新令牌的有效性,并作废旧的令牌组合。
|
||||||
|
*
|
||||||
|
* @param accessToken 旧访问令牌(可能已过期)
|
||||||
|
* @param refreshToken 有效刷新令牌
|
||||||
|
* @return 新的 TokenPair(accessToken + refreshToken)
|
||||||
|
*/
|
||||||
|
fun refreshTokenPair(accessToken: String, refreshToken: String): TokenPair
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成新刷新令牌
|
||||||
|
*
|
||||||
|
* 根据系统策略生成一个安全的、唯一的刷新令牌字符串。
|
||||||
|
* 该令牌通常具有较长的有效期且用于获取新访问令牌。
|
||||||
|
*
|
||||||
|
* @return 生成的刷新令牌字符串
|
||||||
|
*/
|
||||||
|
fun generateRefreshToken(): String
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成访问令牌
|
||||||
|
*
|
||||||
|
* 基于用户详细信息生成一个访问令牌,用于临时认证请求。
|
||||||
|
* 该令牌通常具有较短的有效期,且不能直接用于刷新操作。
|
||||||
|
*
|
||||||
|
* @param userDetails 用户详细信息对象
|
||||||
|
* @return 生成的访问令牌字符串
|
||||||
|
*/
|
||||||
|
fun generateAccessToken(userDetails: Any): String
|
||||||
|
}
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package com.gewuyou.forgeboot.security.authenticate.api.service
|
|
||||||
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户详情服务
|
|
||||||
*
|
|
||||||
* @author gewuyou
|
|
||||||
* @since 2024-11-05 19:34:50
|
|
||||||
*/
|
|
||||||
fun interface UserDetailsService {
|
|
||||||
/**
|
|
||||||
* 根据用户身份标识获取用户
|
|
||||||
* @param principal 用户身份标识 通常为用户名 手机号 邮箱等
|
|
||||||
* @return 用户详情 不能为空
|
|
||||||
*/
|
|
||||||
fun loadUserByPrincipal(principal: Any): UserDetails
|
|
||||||
}
|
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authenticate.api.spec
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.entities.TokenPair
|
||||||
|
import com.gewuyou.forgeboot.webmvc.dto.R
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 双令牌身份验证控制器规格
|
||||||
|
*
|
||||||
|
* 定义了基于双令牌(访问令牌和刷新令牌)的身份验证机制操作规范。
|
||||||
|
* 主要用于处理令牌刷新等核心安全认证交互流程。
|
||||||
|
*
|
||||||
|
* @since 2025-06-26 20:24:40
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
fun interface DualTokenAuthenticationControllerSpec {
|
||||||
|
/**
|
||||||
|
* 刷新访问令牌
|
||||||
|
*
|
||||||
|
* 当访问令牌过期时,通过有效刷新令牌获取一组新的令牌对。
|
||||||
|
* 此方法应校验刷新令牌的有效性,并生成新访问令牌。
|
||||||
|
* 根据实现策略,刷新令牌也可能被更新并返回。
|
||||||
|
*
|
||||||
|
* @param accessToken 过期的访问令牌(通常通过 Authorization 头或请求体传入)
|
||||||
|
* @param refreshToken 有效刷新令牌(用于验证并生成新令牌)
|
||||||
|
* @return 包含新令牌对的响应对象,通常包括新访问令牌和可能更新刷新令牌
|
||||||
|
*/
|
||||||
|
fun refresh(accessToken: String, refreshToken: String): R<TokenPair>
|
||||||
|
}
|
||||||
@ -3,6 +3,9 @@ package com.gewuyou.forgeboot.security.authenticate.api.strategy
|
|||||||
/**
|
/**
|
||||||
* 身份验证处理程序支持策略
|
* 身份验证处理程序支持策略
|
||||||
*
|
*
|
||||||
|
* 该函数式接口定义了身份验证策略需要实现的基本规范,用于标识当前策略支持的登录类型。
|
||||||
|
* 实现类应当通过返回特定的登录类型集合来表明该策略的应用范围。
|
||||||
|
*
|
||||||
* @since 2025-06-11 00:03:28
|
* @since 2025-06-11 00:03:28
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
@ -10,7 +13,11 @@ fun interface AuthenticationHandlerSupportStrategy{
|
|||||||
/**
|
/**
|
||||||
* 获取当前策略支持的登录类型标识符。
|
* 获取当前策略支持的登录类型标识符。
|
||||||
*
|
*
|
||||||
* @return 返回当前策略支持的登录类型字符串
|
* 此方法用于判断当前身份验证策略能够处理的登录请求类型。
|
||||||
|
* 例如:可以基于不同的认证方式(如密码、短信验证码、OAuth等)进行区分。
|
||||||
|
*
|
||||||
|
* @return 返回当前策略支持的登录类型字符串集合
|
||||||
|
* 集合中的每个字符串代表一种支持的登录类型标识符
|
||||||
*/
|
*/
|
||||||
fun supportedLoginType(): String
|
fun supportedLoginTypes(): Set<String>
|
||||||
}
|
}
|
||||||
@ -1,39 +1,19 @@
|
|||||||
package com.gewuyou.forgeboot.security.authenticate.autoconfigure
|
package com.gewuyou.forgeboot.security.authenticate.autoconfigure
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.config.SecurityAuthenticateProperties
|
import com.gewuyou.forgeboot.security.authenticate.api.config.SecurityAuthenticateProperties
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.customizer.LoginFilterCustomizer
|
import com.gewuyou.forgeboot.security.authenticate.api.customizer.LoginFilterCustomizer
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.resolver.LoginRequestResolver
|
import com.gewuyou.forgeboot.security.authenticate.api.customizer.OrderedLoginFilterCustomizer
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.strategy.AuthenticationFailureStrategy
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.strategy.AuthenticationSuccessStrategy
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.strategy.LogoutSuccessStrategy
|
|
||||||
import com.gewuyou.forgeboot.security.core.common.extension.cleanUnNeedConfig
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.filter.UnifiedAuthenticationFilter
|
import com.gewuyou.forgeboot.security.authenticate.impl.filter.UnifiedAuthenticationFilter
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.handler.AuthenticationExceptionHandler
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.handler.CompositeAuthenticationFailureHandler
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.handler.CompositeAuthenticationSuccessHandler
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.handler.CompositeLogoutSuccessHandler
|
import com.gewuyou.forgeboot.security.authenticate.impl.handler.CompositeLogoutSuccessHandler
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.resolver.CompositeLoginRequestResolver
|
import com.gewuyou.forgeboot.security.core.common.extension.cleanUnNeedConfig
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.context.AuthenticationFailureHandlerContext
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.context.AuthenticationSuccessHandlerContext
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.context.LoginRequestConverterContext
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.context.LogoutSuccessHandlerContext
|
|
||||||
import org.springframework.beans.factory.ObjectProvider
|
import org.springframework.beans.factory.ObjectProvider
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||||
import org.springframework.context.ApplicationContext
|
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.ComponentScan
|
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.context.annotation.Primary
|
|
||||||
import org.springframework.security.authentication.AuthenticationManager
|
|
||||||
import org.springframework.security.authentication.AuthenticationProvider
|
|
||||||
import org.springframework.security.authentication.ProviderManager
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint
|
import org.springframework.security.web.AuthenticationEntryPoint
|
||||||
import org.springframework.security.web.SecurityFilterChain
|
import org.springframework.security.web.SecurityFilterChain
|
||||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler
|
|
||||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler
|
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher
|
||||||
|
|
||||||
@ -45,7 +25,7 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher
|
|||||||
* @since 2025-06-11 15:04:58
|
* @since 2025-06-11 15:04:58
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration(proxyBeanMethods = false)
|
||||||
@EnableConfigurationProperties(SecurityAuthenticateProperties::class)
|
@EnableConfigurationProperties(SecurityAuthenticateProperties::class)
|
||||||
class SecurityAuthenticateAutoConfiguration {
|
class SecurityAuthenticateAutoConfiguration {
|
||||||
|
|
||||||
@ -106,204 +86,4 @@ class SecurityAuthenticateAutoConfiguration {
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ForgeBoot安全组件的自动配置类。
|
|
||||||
*
|
|
||||||
* 负责注册多个用于处理身份验证流程的组合式组件,如解析器、上下文、处理器等。
|
|
||||||
*/
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
class ForgeBootSecurityAuthenticateAutoConfiguration {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个组合式的登录请求解析器。
|
|
||||||
*
|
|
||||||
* 将多个 LoginRequestResolver 实现组合成一个统一的接口调用入口。
|
|
||||||
*
|
|
||||||
* @param resolvers 所有可用的 LoginRequestResolver 实例列表
|
|
||||||
* @return 组合后的 CompositeLoginRequestResolver 实例
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
fun compositeLoginRequestResolver(
|
|
||||||
resolvers: List<LoginRequestResolver>,
|
|
||||||
) = CompositeLoginRequestResolver(resolvers)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个登出成功处理的上下文实例。
|
|
||||||
*
|
|
||||||
* 用于根据注册的策略动态选择合适的 LogoutSuccessStrategy。
|
|
||||||
*
|
|
||||||
* @param strategies 所有可用的 LogoutSuccessStrategy 实例列表
|
|
||||||
* @return 初始化好的 LogoutSuccessHandlerContext 实例
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
fun logoutSuccessHandlerContext(
|
|
||||||
strategies: List<LogoutSuccessStrategy>,
|
|
||||||
) = LogoutSuccessHandlerContext(strategies)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个组合式的登出成功处理器。
|
|
||||||
*
|
|
||||||
* 使用解析器和上下文来决定最终使用的登出成功策略。
|
|
||||||
*
|
|
||||||
* @param resolver 登录请求解析器
|
|
||||||
* @param context 登出成功处理上下文
|
|
||||||
* @return 初始化好的 CompositeLogoutSuccessHandler 实例
|
|
||||||
*/
|
|
||||||
@Bean(name = ["logoutSuccessHandler"])
|
|
||||||
fun compositeLogoutSuccessHandler(
|
|
||||||
resolver: CompositeLoginRequestResolver,
|
|
||||||
context: LogoutSuccessHandlerContext,
|
|
||||||
) = CompositeLogoutSuccessHandler(resolver, context)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个认证异常处理器。
|
|
||||||
*
|
|
||||||
* 当用户未认证或认证失败时,通过此处理器响应客户端。
|
|
||||||
*
|
|
||||||
* @param objectMapper JSON 序列化工具
|
|
||||||
* @param properties 安全认证属性配置
|
|
||||||
* @return 初始化好的 AuthenticationExceptionHandler 实例
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
fun authenticationExceptionHandler(
|
|
||||||
objectMapper: ObjectMapper,
|
|
||||||
properties: SecurityAuthenticateProperties,
|
|
||||||
): AuthenticationEntryPoint = AuthenticationExceptionHandler(objectMapper, properties)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个认证管理器。
|
|
||||||
*
|
|
||||||
* 使用一组 AuthenticationProvider 来支持多种认证方式。
|
|
||||||
*
|
|
||||||
* @param authenticationProviders 所有可用的认证提供者
|
|
||||||
* @return 初始化好的 ProviderManager 实例
|
|
||||||
*/
|
|
||||||
@Bean(name = ["authenticationManager"])
|
|
||||||
@Primary
|
|
||||||
fun authenticationManager(
|
|
||||||
authenticationProviders: List<AuthenticationProvider>,
|
|
||||||
): AuthenticationManager = ProviderManager(authenticationProviders)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个认证成功处理的上下文。
|
|
||||||
*
|
|
||||||
* 根据当前请求上下文动态选择合适的认证成功策略。
|
|
||||||
*
|
|
||||||
* @param strategies 所有可用的 AuthenticationSuccessStrategy 实例列表
|
|
||||||
* @return 初始化好的 AuthenticationSuccessHandlerContext 实例
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
fun authenticationSuccessHandlerContext(
|
|
||||||
strategies: List<AuthenticationSuccessStrategy>,
|
|
||||||
) = AuthenticationSuccessHandlerContext(strategies)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个组合式的认证成功处理器。
|
|
||||||
*
|
|
||||||
* 委托给具体的策略实现来进行响应。
|
|
||||||
*
|
|
||||||
* @param resolver 登录请求解析器
|
|
||||||
* @param context 认证成功处理上下文
|
|
||||||
* @return 初始化好的 CompositeAuthenticationSuccessHandler 实例
|
|
||||||
*/
|
|
||||||
@Bean(name = ["authenticationSuccessHandler"])
|
|
||||||
fun authenticationSuccessHandler(
|
|
||||||
resolver: CompositeLoginRequestResolver,
|
|
||||||
context: AuthenticationSuccessHandlerContext,
|
|
||||||
): AuthenticationSuccessHandler = CompositeAuthenticationSuccessHandler(resolver, context)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个认证失败处理的上下文。
|
|
||||||
*
|
|
||||||
* 根据当前请求上下文动态选择合适的认证失败策略。
|
|
||||||
*
|
|
||||||
* @param strategies 所有可用的 AuthenticationFailureStrategy 实例列表
|
|
||||||
* @return 初始化好的 AuthenticationFailureHandlerContext 实例
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
fun authenticationFailureHandlerContext(
|
|
||||||
strategies: List<AuthenticationFailureStrategy>,
|
|
||||||
) = AuthenticationFailureHandlerContext(strategies)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个组合式的认证失败处理器。
|
|
||||||
*
|
|
||||||
* 委托给具体的策略实现来进行响应。
|
|
||||||
*
|
|
||||||
* @param resolver 登录请求解析器
|
|
||||||
* @param context 认证失败处理上下文
|
|
||||||
* @return 初始化好的 CompositeAuthenticationFailureHandler 实例
|
|
||||||
*/
|
|
||||||
@Bean(name = ["authenticationFailureHandler"])
|
|
||||||
fun authenticationFailureHandler(
|
|
||||||
resolver: CompositeLoginRequestResolver,
|
|
||||||
context: AuthenticationFailureHandlerContext,
|
|
||||||
): AuthenticationFailureHandler = CompositeAuthenticationFailureHandler(resolver, context)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个登录请求转换上下文。
|
|
||||||
*
|
|
||||||
* 用于根据当前请求上下文动态选择合适的登录请求转换逻辑。
|
|
||||||
*
|
|
||||||
* @param applicationContext Spring 应用上下文
|
|
||||||
* @return 初始化好的 LoginRequestConverterContext 实例
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
fun loginRequestConverterContext(
|
|
||||||
applicationContext: ApplicationContext,
|
|
||||||
) = LoginRequestConverterContext(applicationContext)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建并返回一个统一的身份验证过滤器。
|
|
||||||
*
|
|
||||||
* 该过滤器是整个认证流程的核心,处理登录请求并触发相应的成功/失败处理器。
|
|
||||||
*
|
|
||||||
* @param properties 安全认证属性配置
|
|
||||||
* @param authenticationManager 认证管理器
|
|
||||||
* @param authenticationSuccessHandler 成功认证处理器
|
|
||||||
* @param authenticationFailureHandler 失败认证处理器
|
|
||||||
* @param compositeLoginRequestResolver 组合登录请求解析器
|
|
||||||
* @param loginRequestConverterContext 登录请求转换上下文
|
|
||||||
* @return 初始化好的 UnifiedAuthenticationFilter 实例
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
fun unifiedAuthenticationFilter(
|
|
||||||
properties: SecurityAuthenticateProperties,
|
|
||||||
authenticationManager: AuthenticationManager,
|
|
||||||
authenticationSuccessHandler: AuthenticationSuccessHandler,
|
|
||||||
authenticationFailureHandler: AuthenticationFailureHandler,
|
|
||||||
compositeLoginRequestResolver: CompositeLoginRequestResolver,
|
|
||||||
loginRequestConverterContext: LoginRequestConverterContext,
|
|
||||||
): UnifiedAuthenticationFilter =
|
|
||||||
UnifiedAuthenticationFilter(
|
|
||||||
AntPathRequestMatcher(
|
|
||||||
properties.baseUrl + properties.loginUrl,
|
|
||||||
properties.loginHttpMethod
|
|
||||||
),
|
|
||||||
authenticationManager,
|
|
||||||
authenticationSuccessHandler,
|
|
||||||
authenticationFailureHandler,
|
|
||||||
compositeLoginRequestResolver,
|
|
||||||
loginRequestConverterContext
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
@ComponentScan(
|
|
||||||
basePackages = [
|
|
||||||
"com.gewuyou.forgeboot.security.authenticate.impl.strategy.impl",
|
|
||||||
"com.gewuyou.forgeboot.security.authenticate.impl.provider.impl",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
class ForgeBootDefaultSecurityAuthenticateAutoConfiguration
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于支持登录过滤器扩展器排序
|
|
||||||
*
|
|
||||||
* 通过 order 属性为 LoginFilterCustomizer 提供排序能力,确保其按预期顺序执行。
|
|
||||||
*/
|
|
||||||
interface OrderedLoginFilterCustomizer : LoginFilterCustomizer {
|
|
||||||
val order: Int
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,256 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authenticate.autoconfigure
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.config.SecurityAuthenticateProperties
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.registry.LoginRequestTypeRegistry
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.resolver.LoginRequestResolver
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.service.UserCacheService
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.strategy.AuthenticationFailureStrategy
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.strategy.AuthenticationSuccessStrategy
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.strategy.LogoutSuccessStrategy
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.filter.UnifiedAuthenticationFilter
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.handler.AuthenticationExceptionHandler
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.handler.CompositeAuthenticationFailureHandler
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.handler.CompositeAuthenticationSuccessHandler
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.handler.CompositeLogoutSuccessHandler
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.registry.SimpleLoginRequestTypeRegistry
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.resolver.CompositeLoginRequestResolver
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.context.AuthenticationFailureHandlerContext
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.context.AuthenticationSuccessHandlerContext
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.context.LoginRequestConverterContext
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.context.LogoutSuccessHandlerContext
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
|
import org.springframework.context.ApplicationContext
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.context.annotation.Primary
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager
|
||||||
|
import org.springframework.security.authentication.AuthenticationProvider
|
||||||
|
import org.springframework.security.authentication.ProviderManager
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint
|
||||||
|
import org.springframework.security.web.authentication.AuthenticationFailureHandler
|
||||||
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler
|
||||||
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher
|
||||||
|
|
||||||
|
/**
|
||||||
|
*安全核心自动配置
|
||||||
|
*
|
||||||
|
* @since 2025-06-27 07:54:04
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
class SecurityCoreAutoConfiguration {
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun bCryptPasswordEncoder(): PasswordEncoder {
|
||||||
|
return BCryptPasswordEncoder()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun nullUserCacheService(): UserCacheService {
|
||||||
|
return object : UserCacheService {
|
||||||
|
override fun getUserFromCache(principal: String): UserDetails? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putUserToCache(userDetails: UserDetails) {
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeUserFromCache(principal: String) {
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个登录请求类型注册器。
|
||||||
|
*
|
||||||
|
* 用于注册和管理不同类型的登录请求,确保系统中所有登录方式能够被统一识别和处理。
|
||||||
|
* 如果上下文中不存在该类型的 Bean,则会使用默认实现 SimpleLoginRequestTypeRegistry。
|
||||||
|
*
|
||||||
|
* @return 实现 LoginRequestTypeRegistry 接口的 Bean 实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun loginRequestTypeRegistry(): LoginRequestTypeRegistry {
|
||||||
|
return SimpleLoginRequestTypeRegistry()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个组合式的登录请求解析器。
|
||||||
|
*
|
||||||
|
* 将多个 LoginRequestResolver 实现组合成一个统一的接口调用入口。
|
||||||
|
*
|
||||||
|
* @param resolvers 所有可用的 LoginRequestResolver 实例列表
|
||||||
|
* @return 组合后的 CompositeLoginRequestResolver 实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
fun compositeLoginRequestResolver(
|
||||||
|
resolvers: List<LoginRequestResolver>,
|
||||||
|
) = CompositeLoginRequestResolver(resolvers)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个登出成功处理的上下文实例。
|
||||||
|
*
|
||||||
|
* 用于根据注册的策略动态选择合适的 LogoutSuccessStrategy。
|
||||||
|
*
|
||||||
|
* @param strategies 所有可用的 LogoutSuccessStrategy 实例列表
|
||||||
|
* @return 初始化好的 LogoutSuccessHandlerContext 实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
fun logoutSuccessHandlerContext(
|
||||||
|
strategies: List<LogoutSuccessStrategy>,
|
||||||
|
) = LogoutSuccessHandlerContext(strategies)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个组合式的登出成功处理器。
|
||||||
|
*
|
||||||
|
* 使用解析器和上下文来决定最终使用的登出成功策略。
|
||||||
|
*
|
||||||
|
* @param resolver 登录请求解析器
|
||||||
|
* @param context 登出成功处理上下文
|
||||||
|
* @return 初始化好的 CompositeLogoutSuccessHandler 实例
|
||||||
|
*/
|
||||||
|
@Bean(name = ["logoutSuccessHandler"])
|
||||||
|
fun compositeLogoutSuccessHandler(
|
||||||
|
resolver: CompositeLoginRequestResolver,
|
||||||
|
context: LogoutSuccessHandlerContext,
|
||||||
|
) = CompositeLogoutSuccessHandler(resolver, context)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个认证异常处理器。
|
||||||
|
*
|
||||||
|
* 当用户未认证或认证失败时,通过此处理器响应客户端。
|
||||||
|
*
|
||||||
|
* @param objectMapper JSON 序列化工具
|
||||||
|
* @param properties 安全认证属性配置
|
||||||
|
* @return 初始化好的 AuthenticationExceptionHandler 实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
fun authenticationExceptionHandler(
|
||||||
|
objectMapper: ObjectMapper,
|
||||||
|
properties: SecurityAuthenticateProperties,
|
||||||
|
): AuthenticationEntryPoint = AuthenticationExceptionHandler(objectMapper, properties)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个认证管理器。
|
||||||
|
*
|
||||||
|
* 使用一组 AuthenticationProvider 来支持多种认证方式。
|
||||||
|
*
|
||||||
|
* @param authenticationProviders 所有可用的认证提供者
|
||||||
|
* @return 初始化好的 ProviderManager 实例
|
||||||
|
*/
|
||||||
|
@Bean(name = ["authenticationManager"])
|
||||||
|
@Primary
|
||||||
|
fun authenticationManager(
|
||||||
|
authenticationProviders: List<AuthenticationProvider>,
|
||||||
|
): AuthenticationManager = ProviderManager(authenticationProviders)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个认证成功处理的上下文。
|
||||||
|
*
|
||||||
|
* 根据当前请求上下文动态选择合适的认证成功策略。
|
||||||
|
*
|
||||||
|
* @param strategies 所有可用的 AuthenticationSuccessStrategy 实例列表
|
||||||
|
* @return 初始化好的 AuthenticationSuccessHandlerContext 实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
fun authenticationSuccessHandlerContext(
|
||||||
|
strategies: List<AuthenticationSuccessStrategy>,
|
||||||
|
) = AuthenticationSuccessHandlerContext(strategies)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个组合式的认证成功处理器。
|
||||||
|
*
|
||||||
|
* 委托给具体的策略实现来进行响应。
|
||||||
|
*
|
||||||
|
* @param resolver 登录请求解析器
|
||||||
|
* @param context 认证成功处理上下文
|
||||||
|
* @return 初始化好的 CompositeAuthenticationSuccessHandler 实例
|
||||||
|
*/
|
||||||
|
@Bean(name = ["authenticationSuccessHandler"])
|
||||||
|
fun authenticationSuccessHandler(
|
||||||
|
resolver: CompositeLoginRequestResolver,
|
||||||
|
context: AuthenticationSuccessHandlerContext,
|
||||||
|
): AuthenticationSuccessHandler = CompositeAuthenticationSuccessHandler(resolver, context)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个认证失败处理的上下文。
|
||||||
|
*
|
||||||
|
* 根据当前请求上下文动态选择合适的认证失败策略。
|
||||||
|
*
|
||||||
|
* @param strategies 所有可用的 AuthenticationFailureStrategy 实例列表
|
||||||
|
* @return 初始化好的 AuthenticationFailureHandlerContext 实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
fun authenticationFailureHandlerContext(
|
||||||
|
strategies: List<AuthenticationFailureStrategy>,
|
||||||
|
) = AuthenticationFailureHandlerContext(strategies)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个组合式的认证失败处理器。
|
||||||
|
*
|
||||||
|
* 委托给具体的策略实现来进行响应。
|
||||||
|
*
|
||||||
|
* @param resolver 登录请求解析器
|
||||||
|
* @param context 认证失败处理上下文
|
||||||
|
* @return 初始化好的 CompositeAuthenticationFailureHandler 实例
|
||||||
|
*/
|
||||||
|
@Bean(name = ["authenticationFailureHandler"])
|
||||||
|
fun authenticationFailureHandler(
|
||||||
|
resolver: CompositeLoginRequestResolver,
|
||||||
|
context: AuthenticationFailureHandlerContext,
|
||||||
|
): AuthenticationFailureHandler = CompositeAuthenticationFailureHandler(resolver, context)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个登录请求转换上下文。
|
||||||
|
*
|
||||||
|
* 用于根据当前请求上下文动态选择合适的登录请求转换逻辑。
|
||||||
|
*
|
||||||
|
* @param applicationContext Spring 应用上下文
|
||||||
|
* @return 初始化好的 LoginRequestConverterContext 实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
fun loginRequestConverterContext(
|
||||||
|
applicationContext: ApplicationContext,
|
||||||
|
) = LoginRequestConverterContext(applicationContext)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并返回一个统一的身份验证过滤器。
|
||||||
|
*
|
||||||
|
* 该过滤器是整个认证流程的核心,处理登录请求并触发相应的成功/失败处理器。
|
||||||
|
*
|
||||||
|
* @param properties 安全认证属性配置
|
||||||
|
* @param authenticationManager 认证管理器
|
||||||
|
* @param authenticationSuccessHandler 成功认证处理器
|
||||||
|
* @param authenticationFailureHandler 失败认证处理器
|
||||||
|
* @param compositeLoginRequestResolver 组合登录请求解析器
|
||||||
|
* @param loginRequestConverterContext 登录请求转换上下文
|
||||||
|
* @return 初始化好的 UnifiedAuthenticationFilter 实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
fun unifiedAuthenticationFilter(
|
||||||
|
properties: SecurityAuthenticateProperties,
|
||||||
|
authenticationManager: AuthenticationManager,
|
||||||
|
authenticationSuccessHandler: AuthenticationSuccessHandler,
|
||||||
|
authenticationFailureHandler: AuthenticationFailureHandler,
|
||||||
|
compositeLoginRequestResolver: CompositeLoginRequestResolver,
|
||||||
|
loginRequestConverterContext: LoginRequestConverterContext,
|
||||||
|
): UnifiedAuthenticationFilter =
|
||||||
|
UnifiedAuthenticationFilter(
|
||||||
|
AntPathRequestMatcher(
|
||||||
|
properties.baseUrl + properties.loginUrl,
|
||||||
|
properties.loginHttpMethod
|
||||||
|
),
|
||||||
|
authenticationManager,
|
||||||
|
authenticationSuccessHandler,
|
||||||
|
authenticationFailureHandler,
|
||||||
|
compositeLoginRequestResolver,
|
||||||
|
loginRequestConverterContext
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authenticate.autoconfigure
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.service.UserCacheService
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.provider.impl.UsernamePasswordAuthenticationProvider
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.security.authentication.AuthenticationProvider
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder
|
||||||
|
|
||||||
|
/**
|
||||||
|
*安全提供程序自动配置
|
||||||
|
*
|
||||||
|
* @since 2025-06-26 22:33:53
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
class SecurityProviderAutoConfiguration {
|
||||||
|
@Bean("usernamePasswordAuthenticationProvider")
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun usernamePasswordAuthenticationProvider(
|
||||||
|
userCacheService: UserCacheService,
|
||||||
|
userDetailsService: UserDetailsService,
|
||||||
|
passwordEncoder: PasswordEncoder
|
||||||
|
): AuthenticationProvider {
|
||||||
|
return UsernamePasswordAuthenticationProvider(
|
||||||
|
userCacheService,
|
||||||
|
userDetailsService,
|
||||||
|
passwordEncoder
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authenticate.autoconfigure
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.config.SecurityAuthenticateProperties
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.strategy.AuthenticationFailureStrategy
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.strategy.AuthenticationSuccessStrategy
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.strategy.LoginRequestConverterStrategy
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.strategy.LogoutSuccessStrategy
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.impl.DefaultAuthenticationFailureStrategy
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.impl.DefaultAuthenticationSuccessStrategy
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.impl.DefaultLogoutSuccessStrategy
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.impl.UsernamePasswordLoginRequestConverterStrategy
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安全策略自动配置类
|
||||||
|
*
|
||||||
|
* 该类定义了多个Bean用于注册认证相关的策略实现,确保系统中存在默认的安全策略处理逻辑。
|
||||||
|
* 所有Bean都使用@ConditionalOnMissingBean注解,表示只有在没有手动定义相应Bean时才会创建默认实例。
|
||||||
|
*
|
||||||
|
* @since 2025-06-27 08:02:26
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
class SecurityStrategyAutoConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建默认的认证成功策略Bean
|
||||||
|
*
|
||||||
|
* 如果上下文中不存在AuthenticationSuccessStrategy类型的Bean,则注册一个默认的实现。
|
||||||
|
* 依赖于ObjectMapper用于序列化/反序列化操作。
|
||||||
|
*
|
||||||
|
* @param objectMapper Jackson的ObjectMapper实例,用于处理JSON数据
|
||||||
|
* @return 默认的认证成功策略实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun defaultAuthenticationSuccessStrategy(objectMapper: ObjectMapper): AuthenticationSuccessStrategy {
|
||||||
|
return DefaultAuthenticationSuccessStrategy(objectMapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建默认的认证失败策略Bean
|
||||||
|
*
|
||||||
|
* 如果上下文中不存在AuthenticationFailureStrategy类型的Bean,则注册一个默认的实现。
|
||||||
|
* 依赖于ObjectMapper和SecurityAuthenticateProperties,用于定制失败响应和配置参数。
|
||||||
|
*
|
||||||
|
* @param objectMapper Jackson的ObjectMapper实例,用于处理JSON数据
|
||||||
|
* @param properties 安全认证相关配置属性,用于定制行为
|
||||||
|
* @return 默认的认证失败策略实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun defaultAuthenticationFailureStrategy(
|
||||||
|
objectMapper: ObjectMapper,
|
||||||
|
properties: SecurityAuthenticateProperties
|
||||||
|
): AuthenticationFailureStrategy {
|
||||||
|
return DefaultAuthenticationFailureStrategy(objectMapper, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建默认的登出成功策略Bean
|
||||||
|
*
|
||||||
|
* 如果上下文中不存在LogoutSuccessStrategy类型的Bean,则注册一个默认的实现。
|
||||||
|
* 依赖于ObjectMapper用于序列化/反序列化操作。
|
||||||
|
*
|
||||||
|
* @param objectMapper Jackson的ObjectMapper实例,用于处理JSON数据
|
||||||
|
* @return 默认的登出成功策略实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun defaultLogoutSuccessStrategy(objectMapper: ObjectMapper): LogoutSuccessStrategy {
|
||||||
|
return DefaultLogoutSuccessStrategy(objectMapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建默认的登录请求转换策略Bean
|
||||||
|
*
|
||||||
|
* 如果上下文中不存在LoginRequestConverterStrategy类型的Bean,则注册一个基于用户名密码的默认实现。
|
||||||
|
* 该Bean指定了名称"usernamePasswordLoginRequestConverterStrategy",以便通过名称引用。
|
||||||
|
*
|
||||||
|
* @return 默认的登录请求转换策略实例
|
||||||
|
*/
|
||||||
|
@Bean("usernamePasswordLoginRequestConverterStrategy")
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun defaultLoginRequestConverterStrategy(): LoginRequestConverterStrategy {
|
||||||
|
return UsernamePasswordLoginRequestConverterStrategy()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1 +1,4 @@
|
|||||||
com.gewuyou.forgeboot.security.authenticate.autoconfigure.SecurityAuthenticateAutoConfiguration
|
com.gewuyou.forgeboot.security.authenticate.autoconfigure.SecurityAuthenticateAutoConfiguration
|
||||||
|
com.gewuyou.forgeboot.security.authenticate.autoconfigure.SecurityProviderAutoConfiguration
|
||||||
|
com.gewuyou.forgeboot.security.authenticate.autoconfigure.SecurityStrategyAutoConfiguration
|
||||||
|
com.gewuyou.forgeboot.security.authenticate.autoconfigure.SecurityCoreAutoConfiguration
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authenticate.impl.controller
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.service.DualTokenAuthenticationService
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.spec.DualTokenAuthenticationControllerSpec
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.constants.SecurityConstants
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.entities.TokenPair
|
||||||
|
import com.gewuyou.forgeboot.webmvc.dto.R
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
|
/**
|
||||||
|
*双令牌身份验证控制器
|
||||||
|
*
|
||||||
|
* @since 2025-06-26 20:40:12
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
class DualTokenAuthenticationController(
|
||||||
|
private val dualTokenAuthenticationService: DualTokenAuthenticationService,
|
||||||
|
): DualTokenAuthenticationControllerSpec {
|
||||||
|
/**
|
||||||
|
* 刷新访问令牌
|
||||||
|
*
|
||||||
|
* 当访问令牌过期时,通过有效刷新令牌获取一组新的令牌对。
|
||||||
|
* 此方法应校验刷新令牌的有效性,并生成新访问令牌。
|
||||||
|
* 根据实现策略,刷新令牌也可能被更新并返回。
|
||||||
|
*
|
||||||
|
* @param accessToken 过期的访问令牌(通常通过 Authorization 头或请求体传入)
|
||||||
|
* @param refreshToken 有效刷新令牌(用于验证并生成新令牌)
|
||||||
|
* @return 包含新令牌对的响应对象,通常包括新访问令牌和可能更新刷新令牌
|
||||||
|
*/
|
||||||
|
@PostMapping("/auth/refresh")
|
||||||
|
override fun refresh(
|
||||||
|
@RequestHeader(SecurityConstants.AUTHORIZATION_HEADER)
|
||||||
|
accessToken: String,
|
||||||
|
@RequestHeader(SecurityConstants.REFRESH_TOKEN_HEADER)
|
||||||
|
refreshToken: String,
|
||||||
|
): R<TokenPair> {
|
||||||
|
return R.success(dualTokenAuthenticationService.refreshTokenPair(accessToken, refreshToken))
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,12 +3,10 @@ package com.gewuyou.forgeboot.security.authenticate.impl.provider
|
|||||||
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.exception.ForgeBootAuthenticationException
|
import com.gewuyou.forgeboot.security.authenticate.api.exception.ForgeBootAuthenticationException
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.service.UserCacheService
|
import com.gewuyou.forgeboot.security.authenticate.api.service.UserCacheService
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.service.UserDetailsService
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.constants.ForgeBootSecurityAuthenticationResponseInformation
|
import com.gewuyou.forgeboot.security.authenticate.impl.constants.ForgeBootSecurityAuthenticationResponseInformation
|
||||||
import org.springframework.security.authentication.AuthenticationProvider
|
import org.springframework.security.authentication.AuthenticationProvider
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.security.core.AuthenticationException
|
import org.springframework.security.core.AuthenticationException
|
||||||
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails
|
import org.springframework.security.core.userdetails.UserDetails
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
@ -21,7 +19,6 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|||||||
*/
|
*/
|
||||||
abstract class AbstractPrincipalCredentialsAuthenticationProvider(
|
abstract class AbstractPrincipalCredentialsAuthenticationProvider(
|
||||||
private val userCacheService: UserCacheService,
|
private val userCacheService: UserCacheService,
|
||||||
private val userDetailsService: UserDetailsService
|
|
||||||
) : AuthenticationProvider {
|
) : AuthenticationProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,19 +76,7 @@ abstract class AbstractPrincipalCredentialsAuthenticationProvider(
|
|||||||
* @return UserDetails 用户详细信息
|
* @return UserDetails 用户详细信息
|
||||||
* @throws ForgeBootAuthenticationException 当 principal 为空或加载失败时抛出异常
|
* @throws ForgeBootAuthenticationException 当 principal 为空或加载失败时抛出异常
|
||||||
*/
|
*/
|
||||||
protected open fun retrieveUser(principal: String): UserDetails {
|
abstract fun retrieveUser(principal: String): UserDetails
|
||||||
if (principal.isBlank()) {
|
|
||||||
ForgeBootAuthenticationException(ForgeBootSecurityAuthenticationResponseInformation.PRINCIPAL_NOT_PROVIDED)
|
|
||||||
}
|
|
||||||
return try {
|
|
||||||
userDetailsService.loadUserByPrincipal(principal)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
throw ForgeBootAuthenticationException(
|
|
||||||
ForgeBootSecurityAuthenticationResponseInformation.INTERNAL_SERVER_ERROR,
|
|
||||||
e
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在验证凭据前进行账户状态检查
|
* 在验证凭据前进行账户状态检查
|
||||||
@ -127,7 +112,8 @@ abstract class AbstractPrincipalCredentialsAuthenticationProvider(
|
|||||||
* @throws ForgeBootAuthenticationException 当凭证为 null 时抛出异常
|
* @throws ForgeBootAuthenticationException 当凭证为 null 时抛出异常
|
||||||
*/
|
*/
|
||||||
protected fun checkCredentialsNotNull(credentials: Any?) {
|
protected fun checkCredentialsNotNull(credentials: Any?) {
|
||||||
credentials ?: ForgeBootAuthenticationException(ForgeBootSecurityAuthenticationResponseInformation.PASSWORD_NOT_PROVIDED)
|
credentials
|
||||||
|
?: ForgeBootAuthenticationException(ForgeBootSecurityAuthenticationResponseInformation.PASSWORD_NOT_PROVIDED)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,6 +143,6 @@ abstract class AbstractPrincipalCredentialsAuthenticationProvider(
|
|||||||
*/
|
*/
|
||||||
protected abstract fun createSuccessAuthentication(
|
protected abstract fun createSuccessAuthentication(
|
||||||
authentication: Authentication,
|
authentication: Authentication,
|
||||||
user: UserDetails
|
user: UserDetails,
|
||||||
): Authentication
|
): Authentication
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,12 +2,12 @@ package com.gewuyou.forgeboot.security.authenticate.impl.provider.impl
|
|||||||
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.exception.ForgeBootAuthenticationException
|
import com.gewuyou.forgeboot.security.authenticate.api.exception.ForgeBootAuthenticationException
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.service.UserCacheService
|
import com.gewuyou.forgeboot.security.authenticate.api.service.UserCacheService
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.service.UserDetailsService
|
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.constants.ForgeBootSecurityAuthenticationResponseInformation
|
import com.gewuyou.forgeboot.security.authenticate.impl.constants.ForgeBootSecurityAuthenticationResponseInformation
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.provider.AbstractPrincipalCredentialsAuthenticationProvider
|
import com.gewuyou.forgeboot.security.authenticate.impl.provider.AbstractPrincipalCredentialsAuthenticationProvider
|
||||||
import com.gewuyou.forgeboot.security.core.common.token.UsernamePasswordAuthenticationToken
|
import com.gewuyou.forgeboot.security.core.common.token.UsernamePasswordAuthenticationToken
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.security.core.userdetails.UserDetails
|
import org.springframework.security.core.userdetails.UserDetails
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder
|
import org.springframework.security.crypto.password.PasswordEncoder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,9 +25,9 @@ import org.springframework.security.crypto.password.PasswordEncoder
|
|||||||
*/
|
*/
|
||||||
class UsernamePasswordAuthenticationProvider(
|
class UsernamePasswordAuthenticationProvider(
|
||||||
userCacheService: UserCacheService,
|
userCacheService: UserCacheService,
|
||||||
userDetailsService: UserDetailsService,
|
private val userDetailsService: UserDetailsService,
|
||||||
private val passwordEncoder: PasswordEncoder
|
private val passwordEncoder: PasswordEncoder
|
||||||
) : AbstractPrincipalCredentialsAuthenticationProvider(userCacheService, userDetailsService) {
|
) : AbstractPrincipalCredentialsAuthenticationProvider(userCacheService) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证用户提供的凭证是否有效。
|
* 验证用户提供的凭证是否有效。
|
||||||
@ -74,4 +74,25 @@ class UsernamePasswordAuthenticationProvider(
|
|||||||
override fun supports(authentication: Class<*>): Boolean {
|
override fun supports(authentication: Class<*>): Boolean {
|
||||||
return UsernamePasswordAuthenticationToken::class.java.isAssignableFrom(authentication)
|
return UsernamePasswordAuthenticationToken::class.java.isAssignableFrom(authentication)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从数据源获取用户信息
|
||||||
|
*
|
||||||
|
* @param principal 用户标识
|
||||||
|
* @return UserDetails 用户详细信息
|
||||||
|
* @throws ForgeBootAuthenticationException 当 principal 为空或加载失败时抛出异常
|
||||||
|
*/
|
||||||
|
override fun retrieveUser(principal: String): UserDetails {
|
||||||
|
if (principal.isBlank()) {
|
||||||
|
ForgeBootAuthenticationException(ForgeBootSecurityAuthenticationResponseInformation.PRINCIPAL_NOT_PROVIDED)
|
||||||
|
}
|
||||||
|
return try {
|
||||||
|
userDetailsService.loadUserByUsername(principal)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw ForgeBootAuthenticationException(
|
||||||
|
ForgeBootSecurityAuthenticationResponseInformation.INTERNAL_SERVER_ERROR,
|
||||||
|
e
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authenticate.impl.registry
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.authenticate.api.registry.LoginRequestTypeRegistry
|
||||||
|
import com.gewuyou.forgeboot.security.core.authenticate.entities.request.LoginRequest
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简单登录请求类型注册表
|
||||||
|
*
|
||||||
|
* 用于管理不同登录类型的请求类映射关系,支持动态注册和获取登录请求类型。
|
||||||
|
*
|
||||||
|
* 示例代码(Kotlin):
|
||||||
|
* ```kt
|
||||||
|
* @Bean
|
||||||
|
* fun loginRequestTypeRegistry(): LoginRequestTypeRegistry {
|
||||||
|
* return LoginRequestTypeRegistry().apply {
|
||||||
|
* register("default", DefaultLoginRequest::class.java)
|
||||||
|
* register("sms", SmsLoginRequest::class.java)
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 示例代码(Java):
|
||||||
|
* ```java
|
||||||
|
* @Bean
|
||||||
|
* public LoginRequestTypeRegistry loginRequestTypeRegistry() {
|
||||||
|
* return new DefaultLoginRequestTypeRegistry()
|
||||||
|
* .register("default", DefaultLoginRequest.class)
|
||||||
|
* .register("sms", SmsLoginRequest.class);
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* ⚠️ 注意:此注册表不是线程安全的,建议仅用于应用启动期间进行注册,不适合运行时动态变更
|
||||||
|
* @since 2025-06-10 16:33:43
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
class SimpleLoginRequestTypeRegistry : LoginRequestTypeRegistry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内部使用可变Map保存登录类型与对应LoginRequest子类的映射关系
|
||||||
|
*/
|
||||||
|
private val mapping = mutableMapOf<String, Class<out LoginRequest>>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册指定登录类型对应的请求类
|
||||||
|
*
|
||||||
|
* 此方法允许将特定的登录类型字符串与相应的LoginRequest实现类进行绑定,
|
||||||
|
* 以便后续可以通过登录类型标识符动态解析出对应的请求类。
|
||||||
|
*
|
||||||
|
* @param loginType 登录类型的标识字符串
|
||||||
|
* @param clazz 继承自LoginRequest的具体请求类
|
||||||
|
* @return 返回当前注册表实例,以支持链式调用
|
||||||
|
*/
|
||||||
|
override fun register(loginType: String, clazz: Class<out LoginRequest>): LoginRequestTypeRegistry {
|
||||||
|
mapping[loginType] = clazz
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据登录类型获取对应的请求类
|
||||||
|
*
|
||||||
|
* 此方法用于查找之前通过register方法注册的登录类型所对应的LoginRequest子类。
|
||||||
|
* 如果未找到匹配的登录类型,则返回null。
|
||||||
|
*
|
||||||
|
* @param loginType 登录类型的标识字符串
|
||||||
|
* @return 返回对应的LoginRequest子类,若未找到则返回null
|
||||||
|
*/
|
||||||
|
override fun getTypeForLoginType(loginType: String): Class<out LoginRequest>? {
|
||||||
|
return mapping[loginType]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,7 +22,7 @@ abstract class AbstractHandlerContext<T : Any, H : Any>(
|
|||||||
/**
|
/**
|
||||||
* 提取策略对应类型的函数,用于确定每个策略的标识
|
* 提取策略对应类型的函数,用于确定每个策略的标识
|
||||||
*/
|
*/
|
||||||
extractType: (T) -> String,
|
extractType: (T) -> Set<String>,
|
||||||
/**
|
/**
|
||||||
* 提取策略对应处理器的函数,用于获取实际可执行的处理器逻辑
|
* 提取策略对应处理器的函数,用于获取实际可执行的处理器逻辑
|
||||||
*/
|
*/
|
||||||
@ -41,23 +41,22 @@ abstract class AbstractHandlerContext<T : Any, H : Any>(
|
|||||||
val map = mutableMapOf<String, H>()
|
val map = mutableMapOf<String, H>()
|
||||||
for (strategy in strategies) {
|
for (strategy in strategies) {
|
||||||
// 提取当前策略的登录类型标识
|
// 提取当前策略的登录类型标识
|
||||||
val loginType = extractType(strategy)
|
val loginTypes = extractType(strategy)
|
||||||
if (loginType == LoginTypes.DEFAULT) {
|
if (loginTypes.contains(LoginTypes.DEFAULT)) {
|
||||||
defaultStrategy = strategy
|
defaultStrategy = strategy
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// 获取当前策略对应的处理器实例
|
// 获取当前策略对应的处理器实例
|
||||||
val handler = extractHandler(strategy)
|
val handler = extractHandler(strategy)
|
||||||
// 检查是否已存在相同类型的处理器
|
log.info("注册${typeName}策略: $loginTypes -> ${strategy::class.java.name}")
|
||||||
val existingHandlerName = map[loginType]?.javaClass?.name
|
loginTypes.forEach { loginType ->
|
||||||
existingHandlerName?.let {
|
if (map.containsKey(loginType)) {
|
||||||
log.warn("重复注册登录类型 [$loginType] 的$typeName,已存在 $existingHandlerName,被 ${strategy::class.java.name} 覆盖")
|
log.warn("已存在 loginType 为 [$loginType] 的$typeName,将覆盖")
|
||||||
}?.run {
|
|
||||||
log.info("注册${typeName}策略: $loginType -> ${strategy::class.java.name}")
|
|
||||||
}
|
}
|
||||||
// 注册或覆盖处理器映射
|
// 注册或覆盖处理器映射
|
||||||
map[loginType] = handler
|
map[loginType] = handler
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// 不可变化处理器映射表
|
// 不可变化处理器映射表
|
||||||
this.handlerMap = map.toMap()
|
this.handlerMap = map.toMap()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,6 @@ class AuthenticationFailureHandlerContext(
|
|||||||
) : AbstractHandlerContext<AuthenticationFailureStrategy, AuthenticationFailureHandler>(
|
) : AbstractHandlerContext<AuthenticationFailureStrategy, AuthenticationFailureHandler>(
|
||||||
strategies,
|
strategies,
|
||||||
"认证失败处理器",
|
"认证失败处理器",
|
||||||
{ it.supportedLoginType() },
|
{ it.supportedLoginTypes() },
|
||||||
{ it }
|
{ it }
|
||||||
)
|
)
|
||||||
@ -15,6 +15,6 @@ class AuthenticationSuccessHandlerContext(
|
|||||||
strategies,
|
strategies,
|
||||||
"认证成功处理器"
|
"认证成功处理器"
|
||||||
,
|
,
|
||||||
{ it.supportedLoginType() },
|
{ it.supportedLoginTypes() },
|
||||||
{ it }
|
{ it }
|
||||||
)
|
)
|
||||||
@ -14,6 +14,6 @@ class LogoutSuccessHandlerContext(
|
|||||||
) : AbstractHandlerContext<LogoutSuccessStrategy, LogoutSuccessHandler>(
|
) : AbstractHandlerContext<LogoutSuccessStrategy, LogoutSuccessHandler>(
|
||||||
strategies,
|
strategies,
|
||||||
"登出处理器",
|
"登出处理器",
|
||||||
{ it.supportedLoginType() },
|
{ it.supportedLoginTypes() },
|
||||||
{ it }
|
{ it }
|
||||||
)
|
)
|
||||||
@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper
|
|||||||
import com.gewuyou.forgeboot.security.authenticate.api.config.SecurityAuthenticateProperties
|
import com.gewuyou.forgeboot.security.authenticate.api.config.SecurityAuthenticateProperties
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.enums.LoginTypes
|
import com.gewuyou.forgeboot.security.authenticate.api.enums.LoginTypes
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.AbstractAuthenticationFailureStrategy
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.AbstractAuthenticationFailureStrategy
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*默认身份验证失败策略
|
*默认身份验证失败策略
|
||||||
@ -12,7 +11,6 @@ import org.springframework.stereotype.Component
|
|||||||
* @since 2025-06-14 20:26:46
|
* @since 2025-06-14 20:26:46
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
@Component("defaultAuthenticationFailureStrategy")
|
|
||||||
class DefaultAuthenticationFailureStrategy(
|
class DefaultAuthenticationFailureStrategy(
|
||||||
objectMapper: ObjectMapper,
|
objectMapper: ObjectMapper,
|
||||||
properties: SecurityAuthenticateProperties
|
properties: SecurityAuthenticateProperties
|
||||||
@ -20,9 +18,13 @@ class DefaultAuthenticationFailureStrategy(
|
|||||||
/**
|
/**
|
||||||
* 获取当前策略支持的登录类型标识符。
|
* 获取当前策略支持的登录类型标识符。
|
||||||
*
|
*
|
||||||
* @return 返回当前策略支持的登录类型字符串
|
* 此方法用于判断当前身份验证策略能够处理的登录请求类型。
|
||||||
|
* 例如:可以基于不同的认证方式(如密码、短信验证码、OAuth等)进行区分。
|
||||||
|
*
|
||||||
|
* @return 返回当前策略支持的登录类型字符串集合
|
||||||
|
* 集合中的每个字符串代表一种支持的登录类型标识符
|
||||||
*/
|
*/
|
||||||
override fun supportedLoginType(): String {
|
override fun supportedLoginTypes(): Set<String> {
|
||||||
return LoginTypes.DEFAULT
|
return setOf(LoginTypes.DEFAULT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,7 +3,6 @@ package com.gewuyou.forgeboot.security.authenticate.impl.strategy.impl
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.enums.LoginTypes
|
import com.gewuyou.forgeboot.security.authenticate.api.enums.LoginTypes
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.AbstractAuthenticationSuccessStrategy
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.AbstractAuthenticationSuccessStrategy
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认身份验证成功策略
|
* 默认身份验证成功策略
|
||||||
@ -15,17 +14,15 @@ import org.springframework.stereotype.Component
|
|||||||
* @since 2025-06-12 22:13:42
|
* @since 2025-06-12 22:13:42
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
@Component("defaultAuthenticationSuccessStrategy")
|
|
||||||
class DefaultAuthenticationSuccessStrategy(
|
class DefaultAuthenticationSuccessStrategy(
|
||||||
objectMapper: ObjectMapper,
|
objectMapper: ObjectMapper,
|
||||||
) : AbstractAuthenticationSuccessStrategy(objectMapper) {
|
) : AbstractAuthenticationSuccessStrategy(objectMapper) {
|
||||||
/**
|
/**
|
||||||
* 获取当前策略支持的登录类型标识
|
* 获取当前策略支持的登录类型标识符。
|
||||||
*
|
*
|
||||||
* 此方法返回 "default" 字符串,表示该策略适用于默认登录类型。
|
* @return 返回当前策略支持的登录类型字符串
|
||||||
* 在多策略环境下,通过此标识来匹配相应的处理逻辑。
|
|
||||||
*
|
|
||||||
* @return 返回支持的登录类型标识字符串
|
|
||||||
*/
|
*/
|
||||||
override fun supportedLoginType(): String = LoginTypes.DEFAULT
|
override fun supportedLoginTypes(): Set<String> {
|
||||||
|
return setOf(LoginTypes.DEFAULT)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -3,25 +3,30 @@ package com.gewuyou.forgeboot.security.authenticate.impl.strategy.impl
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import com.gewuyou.forgeboot.security.authenticate.api.enums.LoginTypes
|
import com.gewuyou.forgeboot.security.authenticate.api.enums.LoginTypes
|
||||||
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.AbstractLogoutSuccessStrategy
|
import com.gewuyou.forgeboot.security.authenticate.impl.strategy.AbstractLogoutSuccessStrategy
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认注销成功策略
|
* 默认注销成功策略
|
||||||
*
|
*
|
||||||
|
* 该类实现了一个默认的注销成功处理策略,用于在用户成功注销时执行相关逻辑。
|
||||||
|
* 继承自 [AbstractLogoutSuccessStrategy],并使用 [objectMapper] 进行 JSON 处理。
|
||||||
|
*
|
||||||
|
* @property objectMapper 用于序列化/反序列化的 Jackson ObjectMapper 实例
|
||||||
* @since 2025-06-14 20:38:16
|
* @since 2025-06-14 20:38:16
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
@Component("defaultLogoutSuccessStrategy")
|
|
||||||
class DefaultLogoutSuccessStrategy(
|
class DefaultLogoutSuccessStrategy(
|
||||||
objectMapper: ObjectMapper
|
objectMapper: ObjectMapper
|
||||||
) : AbstractLogoutSuccessStrategy(objectMapper) {
|
) : AbstractLogoutSuccessStrategy(objectMapper) {
|
||||||
/**
|
/**
|
||||||
* 获取当前策略支持的登录类型标识符。
|
* 获取当前策略支持的登录类型标识符。
|
||||||
*
|
*
|
||||||
* @return 返回当前策略支持的登录类型字符串
|
* 此方法用于判断当前身份验证策略能够处理的登录请求类型。
|
||||||
|
* 例如:可以基于不同的认证方式(如密码、短信验证码、OAuth等)进行区分。
|
||||||
|
*
|
||||||
|
* @return 返回当前策略支持的登录类型字符串集合
|
||||||
|
* 集合中的每个字符串代表一种支持的登录类型标识符
|
||||||
*/
|
*/
|
||||||
override fun supportedLoginType(): String {
|
override fun supportedLoginTypes(): Set<String> {
|
||||||
return LoginTypes.DEFAULT
|
return setOf(LoginTypes.DEFAULT)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -6,14 +6,12 @@ import com.gewuyou.forgeboot.security.core.authenticate.entities.request.LoginRe
|
|||||||
import com.gewuyou.forgeboot.security.core.authenticate.entities.request.UsernamePasswordAuthenticationRequest
|
import com.gewuyou.forgeboot.security.core.authenticate.entities.request.UsernamePasswordAuthenticationRequest
|
||||||
import com.gewuyou.forgeboot.security.core.common.token.UsernamePasswordAuthenticationToken
|
import com.gewuyou.forgeboot.security.core.common.token.UsernamePasswordAuthenticationToken
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户名 密码 认证 Token 转换器策略
|
* 用户名 密码 认证 Token 转换器策略
|
||||||
* @since 2025-02-15 03:25:14
|
* @since 2025-02-15 03:25:14
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
@Component("usernamePasswordLoginRequestConverterStrategy")
|
|
||||||
class UsernamePasswordLoginRequestConverterStrategy : LoginRequestConverterStrategy {
|
class UsernamePasswordLoginRequestConverterStrategy : LoginRequestConverterStrategy {
|
||||||
/**
|
/**
|
||||||
* 转换登录请求为认证对象
|
* 转换登录请求为认证对象
|
||||||
@ -22,7 +20,7 @@ class UsernamePasswordLoginRequestConverterStrategy : LoginRequestConverterStrat
|
|||||||
*/
|
*/
|
||||||
override fun convert(loginRequest: LoginRequest): Authentication {
|
override fun convert(loginRequest: LoginRequest): Authentication {
|
||||||
if (loginRequest is UsernamePasswordAuthenticationRequest) {
|
if (loginRequest is UsernamePasswordAuthenticationRequest) {
|
||||||
return UsernamePasswordAuthenticationToken.Companion.unauthenticated(loginRequest.username, loginRequest.password)
|
return UsernamePasswordAuthenticationToken.unauthenticated(loginRequest.username, loginRequest.password)
|
||||||
}
|
}
|
||||||
throw IllegalArgumentException("Unsupported login request type: ${loginRequest.javaClass.name}")
|
throw IllegalArgumentException("Unsupported login request type: ${loginRequest.javaClass.name}")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.core.common.entities
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌对
|
||||||
|
*
|
||||||
|
* 该类用于封装访问令牌和刷新令牌及其有效期
|
||||||
|
*
|
||||||
|
* @property accessToken 访问令牌,用于身份验证
|
||||||
|
* @property refreshToken 刷新令牌,用于获取新访问令牌
|
||||||
|
* @property expiresIn 访问令牌的有效期,单位为秒
|
||||||
|
*
|
||||||
|
* @since 2025-06-16 13:28:33
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
data class TokenPair(
|
||||||
|
val accessToken: String,
|
||||||
|
val refreshToken: String,
|
||||||
|
val expiresIn: Long
|
||||||
|
)
|
||||||
Loading…
x
Reference in New Issue
Block a user