diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/service/SingleTokenService.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/service/SingleTokenService.kt deleted file mode 100644 index 9a8be4a..0000000 --- a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/service/SingleTokenService.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.gewuyou.forgeboot.security.authorize.api.core.service - -import com.gewuyou.forgeboot.security.core.authorize.entities.SingleTokenPrincipal - -/** - * 单一令牌验证服务接口 - * - * 该接口用于定义对单一令牌的验证操作,通过提供的令牌字符串返回对应的主体信息。 - * - * @since 2025-06-25 13:10:38 - * @author gewuyou - */ -fun interface SingleTokenService { - - /** - * 验证给定的令牌字符串并返回对应的主体信息。 - * - * @param token 要验证的令牌字符串 - * @return 返回与令牌关联的主体信息对象 [SingleTokenPrincipal] - */ - fun validate(token: String): SingleTokenPrincipal -} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/validator/SingleTokenValidator.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/validator/SingleTokenValidator.kt new file mode 100644 index 0000000..fd541e9 --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/validator/SingleTokenValidator.kt @@ -0,0 +1,9 @@ +package com.gewuyou.forgeboot.security.authorize.api.core.validator + +/** + *单令牌验证器 + * + * @since 2025-06-26 15:55:34 + * @author gewuyou + */ +interface SingleTokenValidator: TokenValidator \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/validator/TokenValidator.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/validator/TokenValidator.kt new file mode 100644 index 0000000..e02e370 --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/validator/TokenValidator.kt @@ -0,0 +1,21 @@ +package com.gewuyou.forgeboot.security.authorize.api.core.validator + +/** + * 令牌验证器接口,用于定义通用的令牌验证逻辑 + * + * 该接口设计为泛型接口,支持不同类型的令牌验证结果。 + * + * @since 2025-06-26 15:54:14 + * @author gewuyou + */ +fun interface TokenValidator { + /** + * 验证指定的令牌字符串并返回解析后的结果对象 + * + * @param token 待验证的令牌字符串,通常由客户端在请求头中提供 + * @return 返回解析后的泛型对象 T,可能是用户信息、权限列表或其他业务相关的数据结构 + * @throws IllegalArgumentException 如果令牌格式不正确或为空 + * @throws SecurityException 如果令牌无效或已过期 + */ + fun validate(token: String): T +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/core/SingleTokenSecurityCoreAutoConfiguration.kt b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/core/SingleTokenSecurityCoreAutoConfiguration.kt index 3e52848..5330882 100644 --- a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/core/SingleTokenSecurityCoreAutoConfiguration.kt +++ b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/core/SingleTokenSecurityCoreAutoConfiguration.kt @@ -1,6 +1,6 @@ package com.gewuyou.forgeboot.security.authorize.autoconfigure.core -import com.gewuyou.forgeboot.security.authorize.api.core.service.SingleTokenService +import com.gewuyou.forgeboot.security.authorize.api.core.validator.SingleTokenValidator import com.gewuyou.forgeboot.security.authorize.impl.core.provider.SingleTokenAuthenticationProvider import com.gewuyou.forgeboot.security.core.authorize.entities.SingleTokenPrincipal import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean @@ -16,20 +16,19 @@ import org.springframework.security.authentication.AuthenticationProvider */ @Configuration(proxyBeanMethods = false) class SingleTokenSecurityCoreAutoConfiguration { - /** - * 提供一个默认的 SingleTokenService Bean,用于验证令牌并返回用户主体信息。 + * 提供一个默认的 SingleTokenValidator Bean,用于验证单点登录令牌。 * * 如果上下文中尚未定义此类 Bean,则使用此默认实现。 * 默认实现会在调用 validate 方法时抛出 UnsupportedOperationException, - * 提示使用者应提供自定义的 SingleTokenService 实现。 + * 提示使用者应提供自定义的 SingleTokenValidator 实现。 * - * @return 返回一个 SingleTokenService 接口的默认实现 + * @return 返回一个 SingleTokenValidator 接口的默认实现 */ @Bean @ConditionalOnMissingBean - fun singleTokenService(): SingleTokenService { - return object : SingleTokenService { + fun singleTokenValidator(): SingleTokenValidator { + return object : SingleTokenValidator { /** * 验证给定的 token 并返回对应的用户主体信息。 * @@ -43,18 +42,21 @@ class SingleTokenSecurityCoreAutoConfiguration { } } + /** * 注册 SingleTokenAuthenticationProvider Bean,用于 Spring Security 的认证流程。 * - * 该认证提供者依赖于 SingleTokenService 来完成实际的令牌验证工作。 - * 如果上下文中尚未定义同名 Bean,则注册该 Bean。 + * 该方法创建并返回一个 SingleTokenAuthenticationProvider 实例, + * 用于在 Spring Security 框架中处理基于单点令牌的认证逻辑。 + * 如果上下文中尚未定义同名 Bean,则进行注册。 * - * @param singleTokenService 用于令牌验证的服务实例 - * @return 返回配置好的 SingleTokenAuthenticationProvider 实例 + * @param singleTokenValidator 提供的 SingleTokenValidator 实例, + * 用于执行具体的令牌验证逻辑 + * @return 返回配置好的 AuthenticationProvider 实现类实例 */ @Bean("singleTokenAuthenticationProvider") @ConditionalOnMissingBean - fun singleTokenAuthenticationProvider(singleTokenService: SingleTokenService): AuthenticationProvider { - return SingleTokenAuthenticationProvider(singleTokenService) + fun singleTokenAuthenticationProvider(singleTokenValidator: SingleTokenValidator): AuthenticationProvider { + return SingleTokenAuthenticationProvider(singleTokenValidator) } } \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/provider/SingleTokenAuthenticationProvider.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/provider/SingleTokenAuthenticationProvider.kt index 53aca49..76e4436 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/provider/SingleTokenAuthenticationProvider.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/provider/SingleTokenAuthenticationProvider.kt @@ -1,6 +1,7 @@ package com.gewuyou.forgeboot.security.authorize.impl.core.provider -import com.gewuyou.forgeboot.security.authorize.api.core.service.SingleTokenService +import com.gewuyou.forgeboot.security.authorize.api.core.validator.SingleTokenValidator +import com.gewuyou.forgeboot.security.core.authorize.entities.SingleTokenPrincipal import com.gewuyou.forgeboot.security.core.common.token.SingleTokenAuthenticationToken import org.springframework.security.authentication.AuthenticationProvider import org.springframework.security.core.Authentication @@ -10,34 +11,37 @@ import org.springframework.security.core.Authentication * * 用于处理基于 SingleToken 的身份验证流程。 * - * @property singleTokenService 用于执行 Token 校验的服务组件。 + * @property singleTokenValidator 用于执行 Token 校验的服务组件。 * @author gewuyou * @since 2025-06-25 13:09:43 */ class SingleTokenAuthenticationProvider( - private val singleTokenService: SingleTokenService + private val singleTokenValidator: SingleTokenValidator ) : AuthenticationProvider { /** * 执行身份验证操作。 * - * 将传入的身份验证对象转换为 SingleTokenAuthenticationToken, + * 将传入的身份验证对象转换为 SingleTokenAuthenticationToken 类型, * 然后通过 singleTokenService 验证 Token 的有效性,并返回认证后的 Authentication 对象。 * - * @param authentication 需要被验证的 Authentication 实例。 - * @return 返回已认证的 Authentication 对象。 + * 该方法的主要流程包括: + * 1. 强制类型转换输入的 Authentication 对象为 SingleTokenAuthenticationToken; + * 2. 使用 Token 的 principal 值调用 singleTokenService 进行 Token 校验; + * 3. 构建并返回已认证的 Authentication 实例。 + * + * @param authentication 需要被验证的 Authentication 实例,必须是 SingleTokenAuthenticationToken 类型。 + * @return 返回一个已认证的 Authentication 对象,表示身份验证成功的结果。 */ override fun authenticate(authentication: Authentication): Authentication { + // 转换 Authentication 为 SingleTokenAuthenticationToken 类型 val token = authentication as SingleTokenAuthenticationToken - val tokenInfo = singleTokenService.validate(token.singleToken) - return SingleTokenAuthenticationToken( - token.singleToken, - tokenInfo.principal, - tokenInfo.authorities - ).apply { - isAuthenticated = true - } + // 使用 Token 的 principal 值进行校验,获取 Token 信息 + val tokenInfo = singleTokenValidator.validate(token.principal.toString()) + + // 创建已认证的 Authentication 实例并返回 + return SingleTokenAuthenticationToken.authenticated(tokenInfo, tokenInfo.authorities) } /** @@ -49,6 +53,7 @@ class SingleTokenAuthenticationProvider( * @return 如果支持该类型则返回 true,否则返回 false。 */ override fun supports(authentication: Class<*>): Boolean { + // 检查传入的身份验证类是否是 SingleTokenAuthenticationToken 或其子类 return SingleTokenAuthenticationToken::class.java.isAssignableFrom(authentication) } } diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/filter/SingleTokenAuthenticationFilter.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/filter/SingleTokenAuthenticationFilter.kt index 5d5fec6..d4e846d 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/filter/SingleTokenAuthenticationFilter.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/filter/SingleTokenAuthenticationFilter.kt @@ -40,7 +40,7 @@ class SingleTokenAuthenticationFilter() : OncePerRequestFilter() { if (header?.startsWith(SecurityConstants.BEARER_PREFIX) == true) { val token = header.removePrefix(SecurityConstants.BEARER_PREFIX).trim() // 构造未认证的 token 放入上下文 - val authentication = SingleTokenAuthenticationToken(token, null) + val authentication = SingleTokenAuthenticationToken.unauthenticated(token) SecurityContextHolder.getContext().authentication = authentication } chain.doFilter(request, response) diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/filter/ReactiveSingleTokenAuthenticationFilter.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/filter/ReactiveSingleTokenAuthenticationFilter.kt index d5189ba..192dbb3 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/filter/ReactiveSingleTokenAuthenticationFilter.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/filter/ReactiveSingleTokenAuthenticationFilter.kt @@ -56,8 +56,8 @@ class ReactiveSingleTokenAuthenticationFilter( override fun convert(exchange: ServerWebExchange): Mono? { val headerValue = exchange.request.headers.getFirst(HttpHeaders.AUTHORIZATION) return if (headerValue?.startsWith(SecurityConstants.BEARER_PREFIX, ignoreCase = true) == true) { - val apiKey = headerValue.removePrefix(SecurityConstants.BEARER_PREFIX).trim() - Mono.just(SingleTokenAuthenticationToken(apiKey, null)) + val singleToken = headerValue.removePrefix(SecurityConstants.BEARER_PREFIX).trim() + Mono.just(SingleTokenAuthenticationToken(singleToken, null)) } else { Mono.empty() } diff --git a/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/constants/SecurityConstants.kt b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/constants/SecurityConstants.kt index 6e5760c..7ad4ae8 100644 --- a/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/constants/SecurityConstants.kt +++ b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/constants/SecurityConstants.kt @@ -14,6 +14,11 @@ object SecurityConstants { */ const val AUTHORIZATION_HEADER = "Authorization" + /** + * HTTP请求头中用于携带刷新令牌的字段名称 + */ + const val REFRESH_TOKEN_HEADER="X-Refresh-Token" + /** * Bearer Token前缀,用于在请求头中标识Token类型 */ diff --git a/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/token/SingleTokenAuthenticationToken.kt b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/token/SingleTokenAuthenticationToken.kt index 81b04b9..25858cc 100644 --- a/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/token/SingleTokenAuthenticationToken.kt +++ b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/token/SingleTokenAuthenticationToken.kt @@ -7,37 +7,78 @@ import org.springframework.security.core.GrantedAuthority * 用于单令牌认证的认证令牌实现类。该类扩展了 Spring Security 的 AbstractAuthenticationToken, * 用于表示基于单一令牌(如 API Key)的认证请求。 * - * @param singleToken 存储认证凭据(如API密钥或令牌),不可为 null。 - * @param principal 表示经过认证的主体,可以是用户对象或其他形式的身份标识。 + * @param principal 表示经过认证的主体,可以是用户对象或其他形式的身份标识,不可为 null。 * @param authorities 用户所拥有的权限集合,默认为空列表。 * * @author gewuyou * @since 2025-06-25 13:06:54 */ class SingleTokenAuthenticationToken( - val singleToken: String, - private val principal: Any?, - authorities: Collection = listOf() + private val principal: Any, + authorities: Collection? = null, ) : AbstractAuthenticationToken(authorities) { /** - * 获取认证凭据。 - * - * @return 返回存储在 [singleToken] 中的认证凭据。 + * 初始化方法,根据是否提供权限信息设置认证状态。 + * 如果权限信息为 null,则认证状态设为未认证;否则设为已认证。 */ - override fun getCredentials(): Any = singleToken + init { + if (authorities == null) { + super.setAuthenticated(false) + } else { + super.setAuthenticated(true) + } + } + + companion object { + /** + * 创建一个未认证的 SingleTokenAuthenticationToken 实例。 + * + * @param token 认证凭据(如 API 密钥或令牌),不可为 null。 + * @return 返回未认证的 SingleTokenAuthenticationToken 实例。 + */ + @JvmStatic + fun unauthenticated(token: String): SingleTokenAuthenticationToken { + return SingleTokenAuthenticationToken(token) + } + + /** + * 创建一个已认证的 SingleTokenAuthenticationToken 实例。 + * + * @param principal 表示经过认证的主体,不可为 null。 + * @param authorities 用户所拥有的权限集合,不可为 null。 + * @return 返回已认证的 SingleTokenAuthenticationToken 实例。 + */ + @JvmStatic + fun authenticated( + principal: Any, + authorities: Collection, + ): SingleTokenAuthenticationToken { + return SingleTokenAuthenticationToken(principal.toString(), authorities) + } + } /** - * 获取认证主体。 + * 获取认证凭据。对于单令牌认证来说,凭证通常不适用,因此返回 null。 * - * @return 返回认证主体对象,可能为 null。 + * @return 始终返回 null。 */ - override fun getPrincipal(): Any? = principal + override fun getCredentials(): Any? = null /** - * 判断当前认证是否已完成。 + * 获取认证的主体信息。 * - * @return 如果认证成功则返回 true;否则返回 false。 + * @return 返回认证的主体对象。 */ - override fun isAuthenticated(): Boolean = super.isAuthenticated + override fun getPrincipal(): Any = principal + + /** + * 禁止直接设置认证状态。应使用工厂方法创建已认证或未认证的实例。 + * + * @param authenticated 认证状态,此参数将被忽略。 + * @throws IllegalArgumentException 总是抛出此异常以防止直接修改认证状态。 + */ + override fun setAuthenticated(authenticated: Boolean) { + throw IllegalArgumentException("请使用 factory 方法设置认证状态") + } } \ No newline at end of file