mirror of
https://github.moeyy.xyz/https://github.com/GeWuYou/forgeboot
synced 2025-10-27 20:02:08 +08:00
Compare commits
4 Commits
5f3ae7a5cd
...
8042b45cea
| Author | SHA1 | Date | |
|---|---|---|---|
| 8042b45cea | |||
| 21542adfcc | |||
| aa9bd66259 | |||
| ec326e5a1d |
@ -1,14 +0,0 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.api.config
|
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
|
||||||
|
|
||||||
/**
|
|
||||||
*security 授权属性
|
|
||||||
*
|
|
||||||
* @since 2025-06-15 19:26:20
|
|
||||||
* @author gewuyou
|
|
||||||
*/
|
|
||||||
@ConfigurationProperties(prefix = "forgeboot.security.authorize")
|
|
||||||
class SecurityAuthorizeProperties {
|
|
||||||
var defaultExceptionResponse: String = "Sorry, you don't have access to the resource!"
|
|
||||||
}
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.api.annotations
|
package com.gewuyou.forgeboot.security.authorize.api.core.annotations
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限校验注解,用于标记需要特定权限才能访问的方法
|
* 权限校验注解,用于标记需要特定权限才能访问的方法
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authorize.api.core.config
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Security 授权配置属性类,用于定义安全相关的可配置项
|
||||||
|
*
|
||||||
|
* 该类通过@ConfigurationProperties绑定配置前缀"forgeboot.security.authorize",
|
||||||
|
* 提供了默认异常响应消息、单Token控制及相关路径模式的配置支持。
|
||||||
|
*
|
||||||
|
* @property defaultExceptionResponse 当访问被拒绝时返回的默认提示信息
|
||||||
|
* @property singleToken 单Token配置属性对象,包含启用状态、匹配路径及是否使用授权管理器
|
||||||
|
*
|
||||||
|
* @since 2025-06-15 19:26:20
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties(prefix = "forgeboot.security.authorize")
|
||||||
|
class SecurityAuthorizeProperties {
|
||||||
|
/**
|
||||||
|
* 默认的访问拒绝响应消息,用于在未授权访问时返回给客户端
|
||||||
|
*/
|
||||||
|
var defaultExceptionResponse: String = "Sorry, you don't have access to the resource!"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单Token配置属性实例,用于定义Token相关的行为和路径匹配规则
|
||||||
|
*/
|
||||||
|
var singleToken: SingleTokenProperties = SingleTokenProperties()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单Token配置内部类,封装与Token验证行为相关的配置项
|
||||||
|
*
|
||||||
|
* 用于控制特定路径下的Token验证行为,包括启用状态、路径匹配模式以及是否使用授权管理器。
|
||||||
|
*/
|
||||||
|
class SingleTokenProperties {
|
||||||
|
/**
|
||||||
|
* 控制是否启用API密钥验证功能,默认值为false
|
||||||
|
*/
|
||||||
|
var enabled: Boolean = false
|
||||||
|
/**
|
||||||
|
* 指定是否通过Spring Security的AuthorizationManager进行权限决策,默认为true
|
||||||
|
*/
|
||||||
|
var useAuthorizationManager: Boolean = true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义需要应用Token验证的请求路径模式列表
|
||||||
|
*/
|
||||||
|
var pathPatterns: List<String> = listOf("/api/**")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.api.manager
|
package com.gewuyou.forgeboot.security.authorize.api.core.manager
|
||||||
|
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.api.provider
|
package com.gewuyou.forgeboot.security.authorize.api.core.provider
|
||||||
|
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.api.resolver
|
package com.gewuyou.forgeboot.security.authorize.api.core.resolver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限解析程序接口,用于将请求路径和HTTP方法转换为具体的权限标识符。
|
* 权限解析程序接口,用于将请求路径和HTTP方法转换为具体的权限标识符。
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.api.strategy
|
package com.gewuyou.forgeboot.security.authorize.api.core.strategy
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.provider.PermissionProvider
|
import com.gewuyou.forgeboot.security.authorize.api.core.provider.PermissionProvider
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authorize.api.core.validator
|
||||||
|
|
||||||
|
/**
|
||||||
|
*单令牌验证器
|
||||||
|
*
|
||||||
|
* @since 2025-06-26 15:55:34
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
interface SingleTokenValidator<SingleTokenPrincipal>: TokenValidator<SingleTokenPrincipal>
|
||||||
@ -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<T> {
|
||||||
|
/**
|
||||||
|
* 验证指定的令牌字符串并返回解析后的结果对象
|
||||||
|
*
|
||||||
|
* @param token 待验证的令牌字符串,通常由客户端在请求头中提供
|
||||||
|
* @return 返回解析后的泛型对象 T,可能是用户信息、权限列表或其他业务相关的数据结构
|
||||||
|
* @throws IllegalArgumentException 如果令牌格式不正确或为空
|
||||||
|
* @throws SecurityException 如果令牌无效或已过期
|
||||||
|
*/
|
||||||
|
fun validate(token: String): T
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.api.manager
|
package com.gewuyou.forgeboot.security.authorize.api.servlet.manager
|
||||||
|
|
||||||
import org.springframework.security.authorization.AuthorizationManager
|
import org.springframework.security.authorization.AuthorizationManager
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.api.manager
|
package com.gewuyou.forgeboot.security.authorize.api.webflux.manager
|
||||||
|
|
||||||
import org.springframework.security.authorization.ReactiveAuthorizationManager
|
import org.springframework.security.authorization.ReactiveAuthorizationManager
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.autoconfigure
|
package com.gewuyou.forgeboot.security.authorize.autoconfigure
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.config.SecurityAuthorizeProperties
|
import com.gewuyou.forgeboot.security.authorize.api.core.config.SecurityAuthorizeProperties
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.autoconfigure
|
package com.gewuyou.forgeboot.security.authorize.autoconfigure.core
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.manager.AccessManager
|
import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.provider.PermissionProvider
|
import com.gewuyou.forgeboot.security.authorize.api.core.provider.PermissionProvider
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver
|
import com.gewuyou.forgeboot.security.authorize.api.core.resolver.PermissionResolver
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.strategy.AuthorizationStrategy
|
import com.gewuyou.forgeboot.security.authorize.api.core.strategy.AuthorizationStrategy
|
||||||
import com.gewuyou.forgeboot.security.authorize.impl.manager.DefaultAccessManager
|
import com.gewuyou.forgeboot.security.authorize.impl.core.manager.DefaultAccessManager
|
||||||
import com.gewuyou.forgeboot.security.authorize.impl.resolver.DefaultPermissionResolver
|
import com.gewuyou.forgeboot.security.authorize.impl.core.resolver.DefaultPermissionResolver
|
||||||
import com.gewuyou.forgeboot.security.authorize.impl.strategy.AnyMatchStrategy
|
import com.gewuyou.forgeboot.security.authorize.impl.core.strategy.AnyMatchStrategy
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
@ -20,7 +20,7 @@ import org.springframework.context.annotation.Configuration
|
|||||||
* @since 2025-06-24 16:49:37
|
* @since 2025-06-24 16:49:37
|
||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration(proxyBeanMethods = false)
|
||||||
class ForgeSecurityAuthorizeCoreConfiguration {
|
class ForgeSecurityAuthorizeCoreConfiguration {
|
||||||
/**
|
/**
|
||||||
* 权限解析器Bean,用于将权限表达式解析为具体的权限对象。
|
* 权限解析器Bean,用于将权限表达式解析为具体的权限对象。
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authorize.autoconfigure.core
|
||||||
|
|
||||||
|
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
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.security.authentication.AuthenticationProvider
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置类,用于自动配置单点令牌(Single Token)认证相关的核心组件。
|
||||||
|
*
|
||||||
|
* @since 2025-06-25 15:49:50
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
class SingleTokenSecurityCoreAutoConfiguration {
|
||||||
|
/**
|
||||||
|
* 提供一个默认的 SingleTokenValidator Bean,用于验证单点登录令牌。
|
||||||
|
*
|
||||||
|
* 如果上下文中尚未定义此类 Bean,则使用此默认实现。
|
||||||
|
* 默认实现会在调用 validate 方法时抛出 UnsupportedOperationException,
|
||||||
|
* 提示使用者应提供自定义的 SingleTokenValidator 实现。
|
||||||
|
*
|
||||||
|
* @return 返回一个 SingleTokenValidator 接口的默认实现
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun singleTokenValidator(): SingleTokenValidator<SingleTokenPrincipal> {
|
||||||
|
return object : SingleTokenValidator<SingleTokenPrincipal> {
|
||||||
|
/**
|
||||||
|
* 验证给定的 token 并返回对应的用户主体信息。
|
||||||
|
*
|
||||||
|
* @param token 要验证的令牌字符串
|
||||||
|
* @return 返回包含用户信息的 SingleTokenPrincipal 对象
|
||||||
|
* @throws UnsupportedOperationException 始终抛出异常,提示需要自定义实现
|
||||||
|
*/
|
||||||
|
override fun validate(token: String): SingleTokenPrincipal {
|
||||||
|
throw UnsupportedOperationException("请提供 SingleTokenService 实现")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册 SingleTokenAuthenticationProvider Bean,用于 Spring Security 的认证流程。
|
||||||
|
*
|
||||||
|
* 该方法创建并返回一个 SingleTokenAuthenticationProvider 实例,
|
||||||
|
* 用于在 Spring Security 框架中处理基于单点令牌的认证逻辑。
|
||||||
|
* 如果上下文中尚未定义同名 Bean,则进行注册。
|
||||||
|
*
|
||||||
|
* @param singleTokenValidator 提供的 SingleTokenValidator 实例,
|
||||||
|
* 用于执行具体的令牌验证逻辑
|
||||||
|
* @return 返回配置好的 AuthenticationProvider 实现类实例
|
||||||
|
*/
|
||||||
|
@Bean("singleTokenAuthenticationProvider")
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun singleTokenAuthenticationProvider(singleTokenValidator: SingleTokenValidator<SingleTokenPrincipal>): AuthenticationProvider {
|
||||||
|
return SingleTokenAuthenticationProvider(singleTokenValidator)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,19 +1,24 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.autoconfigure
|
package com.gewuyou.forgeboot.security.authorize.autoconfigure.servlet
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.config.SecurityAuthorizeProperties
|
import com.gewuyou.forgeboot.security.authorize.api.core.config.SecurityAuthorizeProperties
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.manager.AccessManager
|
import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver
|
import com.gewuyou.forgeboot.security.authorize.api.core.resolver.PermissionResolver
|
||||||
import com.gewuyou.forgeboot.security.authorize.impl.adapter.DynamicAuthorizationManagerAdapter
|
import com.gewuyou.forgeboot.security.authorize.impl.servlet.adapter.DynamicAuthorizationManagerAdapter
|
||||||
import com.gewuyou.forgeboot.security.authorize.impl.builder.StatelessSecurityFilterChainRegistrar
|
import com.gewuyou.forgeboot.security.authorize.impl.servlet.handler.AuthorizationExceptionHandler
|
||||||
import com.gewuyou.forgeboot.security.authorize.impl.handler.AuthorizationExceptionHandler
|
import com.gewuyou.forgeboot.security.authorize.impl.servlet.registrar.StatelessSecurityFilterChainRegistrar
|
||||||
import com.gewuyou.forgeboot.security.core.common.builder.SecurityFilterChainRegistrar
|
import com.gewuyou.forgeboot.security.core.common.constants.SecurityConstants
|
||||||
import com.gewuyou.forgeboot.security.core.common.customizer.HttpSecurityCustomizer
|
import com.gewuyou.forgeboot.security.core.common.customizer.HttpSecurityCustomizer
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.registrar.SecurityFilterChainRegistrar
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
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.authorization.AuthorizationManager
|
import org.springframework.security.authorization.AuthorizationManager
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
import org.springframework.security.web.SecurityFilterChain
|
import org.springframework.security.web.SecurityFilterChain
|
||||||
@ -28,11 +33,26 @@ import org.springframework.security.web.util.matcher.AnyRequestMatcher
|
|||||||
* @author gewuyou
|
* @author gewuyou
|
||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnProperty(name = ["spring.main.web-application-type"], havingValue = "servlet", matchIfMissing = true)
|
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||||
class ServletAuthorizeSecurityConfiguration(
|
class ServletAuthorizeSecurityConfiguration(
|
||||||
private val accessManager: AccessManager,
|
private val accessManager: AccessManager,
|
||||||
private val permissionResolver: PermissionResolver,
|
private val permissionResolver: PermissionResolver,
|
||||||
) {
|
) {
|
||||||
|
/**
|
||||||
|
* 创建并返回一个认证管理器。
|
||||||
|
*
|
||||||
|
* 初始化一个基于提供的认证提供者的认证管理器,用于支持多种认证方式。
|
||||||
|
*
|
||||||
|
* @param authenticationProviders 所有可用的认证提供者列表
|
||||||
|
* @return 返回初始化好的 AuthenticationManager 实例,具体实现为 ProviderManager
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Primary
|
||||||
|
@ConditionalOnBean
|
||||||
|
fun authenticationManager(
|
||||||
|
authenticationProviders: List<AuthenticationProvider>,
|
||||||
|
): AuthenticationManager = ProviderManager(authenticationProviders)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建默认的安全过滤链,适用于 Servlet 编程模型
|
* 创建默认的安全过滤链,适用于 Servlet 编程模型
|
||||||
*
|
*
|
||||||
@ -42,13 +62,13 @@ class ServletAuthorizeSecurityConfiguration(
|
|||||||
* @throws Exception 构建过程中可能抛出的异常
|
* @throws Exception 构建过程中可能抛出的异常
|
||||||
*/
|
*/
|
||||||
@Bean(name = ["defaultSecurityFilterChain"])
|
@Bean(name = ["defaultSecurityFilterChain"])
|
||||||
@ConditionalOnBean(SecurityFilterChainRegistrar::class)
|
@ConditionalOnBean
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun defaultSecurityFilterChain(
|
fun defaultSecurityFilterChain(
|
||||||
registrar: SecurityFilterChainRegistrar,
|
registrar: SecurityFilterChainRegistrar,
|
||||||
http: HttpSecurity,
|
http: HttpSecurity,
|
||||||
): SecurityFilterChain = registrar.buildChain(
|
): SecurityFilterChain = registrar.buildChain(
|
||||||
"default",
|
SecurityConstants.DEFAULT_CHAIN_ID,
|
||||||
http,
|
http,
|
||||||
AnyRequestMatcher.INSTANCE
|
AnyRequestMatcher.INSTANCE
|
||||||
) { config ->
|
) { config ->
|
||||||
@ -0,0 +1,134 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authorize.autoconfigure.servlet
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.authorize.api.core.config.SecurityAuthorizeProperties
|
||||||
|
import com.gewuyou.forgeboot.security.authorize.impl.servlet.customizer.SingleTokenHttpSecurityCustomizer
|
||||||
|
import com.gewuyou.forgeboot.security.authorize.impl.servlet.filter.SingleTokenAuthenticationFilter
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.constants.SecurityConstants
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.customizer.HttpSecurityCustomizer
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.registrar.SecurityFilterChainRegistrar
|
||||||
|
import jakarta.servlet.Filter
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.security.authorization.AuthorizationManager
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
|
import org.springframework.security.web.SecurityFilterChain
|
||||||
|
import org.springframework.security.web.access.intercept.RequestAuthorizationContext
|
||||||
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher
|
||||||
|
import org.springframework.security.web.util.matcher.OrRequestMatcher
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single Token安全自动配置类,用于在 Servlet Web 应用中自动装配与 Single Token相关的安全组件。
|
||||||
|
*
|
||||||
|
* 此配置仅在以下条件下生效:
|
||||||
|
* 1. 应用类型为 Servlet;
|
||||||
|
* 2. 配置项 "forgeboot.security.authorize.single-token.enabled" 为 true。
|
||||||
|
*
|
||||||
|
* @property securityAuthorizeProperties 安全授权配置属性,用于获取 Single Token相关路径等信息
|
||||||
|
* @since 2025-06-25 13:41:56
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||||
|
@ConditionalOnProperty(
|
||||||
|
prefix = "forgeboot.security.authorize.single-token",
|
||||||
|
name = ["enabled"],
|
||||||
|
havingValue = "true",
|
||||||
|
matchIfMissing = false
|
||||||
|
)
|
||||||
|
class ServletSingleTokenSecurityAutoConfiguration(
|
||||||
|
private val securityAuthorizeProperties: SecurityAuthorizeProperties,
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* 创建 Single Token认证过滤器 Bean。
|
||||||
|
*
|
||||||
|
* 构建一个 SingleTokenAuthenticationFilter 实例作为 Spring Bean,
|
||||||
|
* 该过滤器用于处理基于 Single Token 的身份验证逻辑。
|
||||||
|
*
|
||||||
|
* @return 返回构建完成的 Filter 接口实现对象(即 SingleTokenAuthenticationFilter)
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(name = ["singleTokenAuthenticationFilter"])
|
||||||
|
fun singleTokenAuthenticationFilter(): Filter {
|
||||||
|
return SingleTokenAuthenticationFilter()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提供一个用于自定义 HTTP 安全配置的 Single Token安全自定义器 Bean。
|
||||||
|
*
|
||||||
|
* 如果容器中尚不存在同名 Bean,则创建并返回 SingleTokenHttpSecurityCustomizer 实例。
|
||||||
|
* 此自定义器将注入的认证过滤器用于构建定制化的安全配置,实现对 HttpSecurity 的扩展。
|
||||||
|
*
|
||||||
|
* @param singleTokenAuthenticationFilter 注入已配置的认证过滤器,用于请求处理
|
||||||
|
* @return 返回 HttpSecurityCustomizer 的具体实现对象
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun singleTokenHttpSecurityCustomizer(
|
||||||
|
@Qualifier("singleTokenAuthenticationFilter")
|
||||||
|
singleTokenAuthenticationFilter: Filter,
|
||||||
|
): HttpSecurityCustomizer {
|
||||||
|
return SingleTokenHttpSecurityCustomizer(singleTokenAuthenticationFilter)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建默认的安全过滤链,适用于 Servlet 编程模型。
|
||||||
|
*
|
||||||
|
* 此方法基于配置的路径模式构建一个复合请求匹配器,并通过注册器创建对应的 SingleToken 安全过滤链。
|
||||||
|
* 过滤链根据配置决定是否使用授权管理器进行访问控制,提供两种模式:
|
||||||
|
* - 使用授权管理器时:所有请求通过指定的 authorizeManager 进行访问控制
|
||||||
|
* - 不使用授权管理器时:要求所有请求必须经过身份验证
|
||||||
|
*
|
||||||
|
* @param registrar 安全过滤链注册器,用于构建和管理过滤链
|
||||||
|
* @param http Spring Security 的 HttpSecurity 配置对象
|
||||||
|
* @param authorizeManager 授权管理器,用于在启用授权管理时定义访问策略
|
||||||
|
* @return 构建完成的安全过滤链实例
|
||||||
|
*/
|
||||||
|
@Bean(name = ["defaultSingleTokenSecurityFilterChain"])
|
||||||
|
fun defaultSingleTokenSecurityFilterChain(
|
||||||
|
registrar: SecurityFilterChainRegistrar,
|
||||||
|
http: HttpSecurity,
|
||||||
|
authorizeManager: AuthorizationManager<RequestAuthorizationContext>
|
||||||
|
): SecurityFilterChain {
|
||||||
|
// 从配置中获取 singleToken 适用的路径模式(如:["/api/**", "/open/**"])
|
||||||
|
val patterns = securityAuthorizeProperties.singleToken.pathPatterns
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将每个路径模式转换为 AntPathRequestMatcher 实例
|
||||||
|
*/
|
||||||
|
val matchers = patterns.map { AntPathRequestMatcher(it) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 OrRequestMatcher 组合所有路径匹配规则,实现多路径匹配支持
|
||||||
|
*/
|
||||||
|
val combinedMatcher = OrRequestMatcher(matchers)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用注册器构建安全链,指定链 ID、HttpSecurity 对象和请求匹配器
|
||||||
|
*/
|
||||||
|
return registrar.buildChain(
|
||||||
|
SecurityConstants.SINGLE_TOKEN_CHAIN_ID,
|
||||||
|
http,
|
||||||
|
combinedMatcher
|
||||||
|
) { config ->
|
||||||
|
if (securityAuthorizeProperties.singleToken.useAuthorizationManager) {
|
||||||
|
/**
|
||||||
|
* 启用授权管理器时,配置请求通过指定的 authorizeManager 进行访问控制
|
||||||
|
*/
|
||||||
|
config.authorizeHttpRequests {
|
||||||
|
it.anyRequest().access(authorizeManager)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* 禁用授权管理器时,要求所有请求必须经过身份验证
|
||||||
|
*/
|
||||||
|
config.authorizeHttpRequests {
|
||||||
|
it.anyRequest().authenticated()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,26 +1,32 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.autoconfigure
|
package com.gewuyou.forgeboot.security.authorize.autoconfigure.webflux
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.config.SecurityAuthorizeProperties
|
import com.gewuyou.forgeboot.security.authorize.api.core.config.SecurityAuthorizeProperties
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.manager.AccessManager
|
import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver
|
import com.gewuyou.forgeboot.security.authorize.api.core.resolver.PermissionResolver
|
||||||
import com.gewuyou.forgeboot.security.authorize.impl.adapter.DynamicReactiveAuthorizationManagerAdapter
|
import com.gewuyou.forgeboot.security.authorize.impl.webflux.adapter.DynamicReactiveAuthorizationManagerAdapter
|
||||||
import com.gewuyou.forgeboot.security.authorize.impl.builder.StatelessSecurityWebFilterChainRegistrar
|
import com.gewuyou.forgeboot.security.authorize.impl.webflux.handler.ReactiveAuthorizationExceptionHandler
|
||||||
import com.gewuyou.forgeboot.security.authorize.impl.handler.ReactiveAuthorizationExceptionHandler
|
import com.gewuyou.forgeboot.security.authorize.impl.webflux.registrar.StatelessSecurityWebFilterChainRegistrar
|
||||||
import com.gewuyou.forgeboot.security.core.common.builder.SecurityWebFilterChainRegistrar
|
import com.gewuyou.forgeboot.security.core.common.constants.SecurityConstants
|
||||||
import com.gewuyou.forgeboot.security.core.common.customizer.ServerHttpSecurityCustomizer
|
import com.gewuyou.forgeboot.security.core.common.customizer.ServerHttpSecurityCustomizer
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.registrar.SecurityWebFilterChainRegistrar
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.context.annotation.Primary
|
||||||
|
import org.springframework.security.authentication.AuthenticationProvider
|
||||||
|
import org.springframework.security.authentication.ProviderManager
|
||||||
|
import org.springframework.security.authentication.ReactiveAuthenticationManager
|
||||||
|
import org.springframework.security.authentication.ReactiveAuthenticationManagerAdapter
|
||||||
import org.springframework.security.authorization.ReactiveAuthorizationManager
|
import org.springframework.security.authorization.ReactiveAuthorizationManager
|
||||||
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
|
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
|
||||||
import org.springframework.security.config.web.server.ServerHttpSecurity
|
import org.springframework.security.config.web.server.ServerHttpSecurity
|
||||||
import org.springframework.security.web.server.SecurityWebFilterChain
|
import org.springframework.security.web.server.SecurityWebFilterChain
|
||||||
import org.springframework.security.web.server.authorization.AuthorizationContext
|
import org.springframework.security.web.server.authorization.AuthorizationContext
|
||||||
import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler
|
import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler
|
||||||
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers.anyExchange
|
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反应式授权配置
|
* 反应式授权配置
|
||||||
@ -31,7 +37,7 @@ import org.springframework.security.web.server.util.matcher.ServerWebExchangeMat
|
|||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@EnableWebFluxSecurity
|
@EnableWebFluxSecurity
|
||||||
@ConditionalOnProperty(name = ["spring.main.web-application-type"], havingValue = "reactive")
|
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||||
class ReactiveAuthorizeSecurityConfiguration(
|
class ReactiveAuthorizeSecurityConfiguration(
|
||||||
private val accessManager: AccessManager,
|
private val accessManager: AccessManager,
|
||||||
private val permissionResolver: PermissionResolver,
|
private val permissionResolver: PermissionResolver,
|
||||||
@ -54,9 +60,9 @@ class ReactiveAuthorizeSecurityConfiguration(
|
|||||||
http: ServerHttpSecurity,
|
http: ServerHttpSecurity,
|
||||||
): SecurityWebFilterChain = registrar
|
): SecurityWebFilterChain = registrar
|
||||||
.buildChain(
|
.buildChain(
|
||||||
"default",
|
SecurityConstants.DEFAULT_CHAIN_ID,
|
||||||
http,
|
http,
|
||||||
anyExchange()
|
ServerWebExchangeMatchers.anyExchange()
|
||||||
) { it: ServerHttpSecurity ->
|
) { it: ServerHttpSecurity ->
|
||||||
it.authorizeExchange {
|
it.authorizeExchange {
|
||||||
it.anyExchange().denyAll()
|
it.anyExchange().denyAll()
|
||||||
@ -93,6 +99,31 @@ class ReactiveAuthorizeSecurityConfiguration(
|
|||||||
return DynamicReactiveAuthorizationManagerAdapter(accessManager, permissionResolver)
|
return DynamicReactiveAuthorizationManagerAdapter(accessManager, permissionResolver)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 反应式认证管理器
|
||||||
|
* 创建并返回一个主认证管理器实例,用于处理响应式编程环境中的身份验证请求。
|
||||||
|
* 该管理器基于提供的认证提供者列表进行初始化。
|
||||||
|
*
|
||||||
|
* 此方法通过将传统的 ProviderManager 包装在 ReactiveAuthenticationManagerAdapter 中,
|
||||||
|
* 实现了对响应式编程模型的支持。ProviderManager 被构造为使用给定的认证提供者列表,
|
||||||
|
* 并作为适配器的一部分来完成异步的身份验证逻辑。
|
||||||
|
*
|
||||||
|
* @param authenticationProviders 认证提供者列表,用于执行具体的身份验证逻辑。
|
||||||
|
* 每个提供者负责特定类型的身份验证机制。
|
||||||
|
* @return 初始化后的 ReactiveAuthenticationManager 实例,用于响应式环境下的身份验证流程。
|
||||||
|
* 返回的对象是 ReactiveAuthenticationManagerAdapter 的实例,其内部封装了同步的 ProviderManager。
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Primary
|
||||||
|
@ConditionalOnBean
|
||||||
|
fun reactiveAuthenticationManager(
|
||||||
|
authenticationProviders: List<AuthenticationProvider>
|
||||||
|
): ReactiveAuthenticationManager {
|
||||||
|
return ReactiveAuthenticationManagerAdapter(
|
||||||
|
ProviderManager(authenticationProviders)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 无状态安全过滤链注册器
|
* 无状态安全过滤链注册器
|
||||||
* 创建并返回一个无状态的安全过滤链注册器,用于注册需要无状态处理的安全过滤链。
|
* 创建并返回一个无状态的安全过滤链注册器,用于注册需要无状态处理的安全过滤链。
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authorize.autoconfigure.webflux
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.authorize.api.core.config.SecurityAuthorizeProperties
|
||||||
|
import com.gewuyou.forgeboot.security.authorize.impl.webflux.customizer.SingleTokenServerHttpSecurityCustomizer
|
||||||
|
import com.gewuyou.forgeboot.security.authorize.impl.webflux.filter.ReactiveSingleTokenAuthenticationFilter
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.constants.SecurityConstants
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.customizer.ServerHttpSecurityCustomizer
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.registrar.SecurityWebFilterChainRegistrar
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
|
||||||
|
import org.springframework.security.authentication.ReactiveAuthenticationManager
|
||||||
|
import org.springframework.security.authorization.ReactiveAuthorizationManager
|
||||||
|
import org.springframework.security.config.web.server.ServerHttpSecurity
|
||||||
|
import org.springframework.security.web.server.SecurityWebFilterChain
|
||||||
|
import org.springframework.security.web.server.authorization.AuthorizationContext
|
||||||
|
import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher
|
||||||
|
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher
|
||||||
|
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers
|
||||||
|
import org.springframework.web.server.WebFilter
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置类,用于在满足条件时自动配置基于 Single Token 的反应式安全机制。
|
||||||
|
*
|
||||||
|
* 仅在满足以下条件时生效:
|
||||||
|
* - 应用类型为 REACTIVE(反应式应用)
|
||||||
|
* - 配置项 `forgeboot.security.authorize.single-token.enabled` 被设置为 true
|
||||||
|
*
|
||||||
|
* @property securityAuthorizeProperties 安全授权配置属性,用于获取 Single Token 的路径匹配规则等信息
|
||||||
|
* @since 2025-06-25 21:04:37
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||||
|
@ConditionalOnProperty(
|
||||||
|
prefix = "forgeboot.security.authorize.single-token",
|
||||||
|
name = ["enabled"],
|
||||||
|
havingValue = "true",
|
||||||
|
matchIfMissing = false
|
||||||
|
)
|
||||||
|
class ReactiveSingleTokenSecurityAutoConfiguration(
|
||||||
|
private val securityAuthorizeProperties: SecurityAuthorizeProperties
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并注册名为 reactiveSingleTokenAuthenticationFilter 的 WebFilter Bean。
|
||||||
|
*
|
||||||
|
* 该过滤器负责处理基于 Single Token 的认证逻辑,确保请求携带有效的 Token。
|
||||||
|
* 仅当容器中尚未存在同名的 Bean 时才会创建此实例。
|
||||||
|
*
|
||||||
|
* @param reactiveAuthenticationManager 反应式认证管理器,用于执行认证操作
|
||||||
|
* @return 构建完成的 WebFilter 实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(name = ["reactiveSingleTokenAuthenticationFilter"])
|
||||||
|
fun singleTokenAuthenticationFilter(
|
||||||
|
reactiveAuthenticationManager: ReactiveAuthenticationManager
|
||||||
|
): WebFilter {
|
||||||
|
return ReactiveSingleTokenAuthenticationFilter(reactiveAuthenticationManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并注册 ServerHttpSecurityCustomizer 的 Bean,用于定制 Single Token 安全配置。
|
||||||
|
*
|
||||||
|
* 此自定义器用于在构建 Spring Security 过滤器链时插入 Single Token 认证逻辑。
|
||||||
|
* 仅当容器中尚未存在相同类型的 Bean 时才会创建此实例。
|
||||||
|
*
|
||||||
|
* @param reactiveSingleTokenAuthenticationFilter 使用指定名称从 Spring 容器中注入的 Single Token 反应式认证过滤器 Bean。
|
||||||
|
* 该过滤器负责处理实际的 Single Token 认证逻辑。
|
||||||
|
*
|
||||||
|
* @return 构建完成的 ServerHttpSecurityCustomizer 实例,用于在安全配置中添加 Single Token 相关逻辑。
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
fun singleTokenServerHttpSecurityCustomizer(
|
||||||
|
@Qualifier("reactiveSingleTokenAuthenticationFilter")
|
||||||
|
reactiveSingleTokenAuthenticationFilter: WebFilter,
|
||||||
|
): ServerHttpSecurityCustomizer {
|
||||||
|
return SingleTokenServerHttpSecurityCustomizer(reactiveSingleTokenAuthenticationFilter)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并注册基于 Single Token 认证的 WebFlux 安全过滤器链。
|
||||||
|
*
|
||||||
|
* 该方法利用 SecurityWebFilterChainRegistrar 注册一个具有路径匹配规则的安全过滤器链,
|
||||||
|
* 仅对符合配置中指定路径模式的请求生效,并要求通过 Single Token 认证。
|
||||||
|
*
|
||||||
|
* @param registrar 用于注册和构建安全过滤器链的核心工具类,负责链的组装过程。
|
||||||
|
* @param http Spring Security 提供的 ServerHttpSecurity 实例,用于构建 HTTP 安全配置。
|
||||||
|
* @param reactiveAuthorizationManager 反应式授权管理器,用于在使用授权管理逻辑时提供访问控制。
|
||||||
|
* @return 构建完成的 SecurityWebFilterChain 实例,表示定义好的安全过滤器链。
|
||||||
|
*
|
||||||
|
* 关键逻辑总结:
|
||||||
|
* 1. 获取配置中的路径模式列表 patterns;
|
||||||
|
* 2. 将每个路径转换为 ServerWebExchangeMatcher 实例,形成 matchers 列表;
|
||||||
|
* 3. 合并所有 matcher 形成 combinedMatcher 复合匹配规则;
|
||||||
|
* 4. 利用 registrar 构建过滤器链,并根据 useAuthorizationManager 配置决定采用何种认证方式:
|
||||||
|
* - 若启用 authorizationManager,则通过 access 方法设置自定义的授权逻辑;
|
||||||
|
* - 否则直接要求请求必须经过认证。
|
||||||
|
*/
|
||||||
|
@Bean(name = ["defaultSingleTokenSecurityWebFilterChain"])
|
||||||
|
fun defaultSingleTokenSecurityWebFilterChain(
|
||||||
|
registrar: SecurityWebFilterChainRegistrar,
|
||||||
|
http: ServerHttpSecurity,
|
||||||
|
reactiveAuthorizationManager: ReactiveAuthorizationManager<AuthorizationContext>
|
||||||
|
): SecurityWebFilterChain {
|
||||||
|
val patterns = securityAuthorizeProperties.singleToken.pathPatterns
|
||||||
|
val matchers = patterns.map { PathPatternParserServerWebExchangeMatcher(it) }
|
||||||
|
val combinedMatcher: ServerWebExchangeMatcher =
|
||||||
|
ServerWebExchangeMatchers.matchers(*matchers.toTypedArray())
|
||||||
|
return registrar.buildChain(
|
||||||
|
SecurityConstants.SINGLE_TOKEN_CHAIN_ID,
|
||||||
|
http,
|
||||||
|
combinedMatcher
|
||||||
|
) { config ->
|
||||||
|
if (securityAuthorizeProperties.singleToken.useAuthorizationManager) {
|
||||||
|
config.authorizeExchange {
|
||||||
|
it.anyExchange().access(reactiveAuthorizationManager)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
config.authorizeExchange {
|
||||||
|
it.anyExchange().authenticated()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,7 @@
|
|||||||
com.gewuyou.forgeboot.security.authorize.autoconfigure.ForgeSecurityAuthorizeCoreConfiguration
|
|
||||||
com.gewuyou.forgeboot.security.authorize.autoconfigure.ReactiveAuthorizeSecurityConfiguration
|
|
||||||
com.gewuyou.forgeboot.security.authorize.autoconfigure.ForgeSecurityAuthorizeAutoConfiguration
|
com.gewuyou.forgeboot.security.authorize.autoconfigure.ForgeSecurityAuthorizeAutoConfiguration
|
||||||
com.gewuyou.forgeboot.security.authorize.autoconfigure.ServletAuthorizeSecurityConfiguration
|
com.gewuyou.forgeboot.security.authorize.autoconfigure.core.ForgeSecurityAuthorizeCoreConfiguration
|
||||||
|
com.gewuyou.forgeboot.security.authorize.autoconfigure.core.SingleTokenSecurityCoreAutoConfiguration
|
||||||
|
com.gewuyou.forgeboot.security.authorize.autoconfigure.webflux.ReactiveAuthorizeSecurityConfiguration
|
||||||
|
com.gewuyou.forgeboot.security.authorize.autoconfigure.webflux.ReactiveSingleTokenSecurityAutoConfiguration
|
||||||
|
com.gewuyou.forgeboot.security.authorize.autoconfigure.servlet.ServletAuthorizeSecurityConfiguration
|
||||||
|
com.gewuyou.forgeboot.security.authorize.autoconfigure.servlet.ServletSingleTokenSecurityAutoConfiguration
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.aspect
|
package com.gewuyou.forgeboot.security.authorize.impl.core.aspect
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.annotations.RequiresPermission
|
import com.gewuyou.forgeboot.security.authorize.api.core.annotations.RequiresPermission
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.manager.AccessManager
|
import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.strategy.AuthorizationStrategy
|
import com.gewuyou.forgeboot.security.authorize.api.core.strategy.AuthorizationStrategy
|
||||||
import com.gewuyou.forgeboot.security.authorize.impl.resolver.SpELResolver
|
import com.gewuyou.forgeboot.security.authorize.impl.core.resolver.SpELResolver
|
||||||
import org.aspectj.lang.ProceedingJoinPoint
|
import org.aspectj.lang.ProceedingJoinPoint
|
||||||
import org.aspectj.lang.annotation.Around
|
import org.aspectj.lang.annotation.Around
|
||||||
import org.aspectj.lang.annotation.Aspect
|
import org.aspectj.lang.annotation.Aspect
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.manager
|
package com.gewuyou.forgeboot.security.authorize.impl.core.manager
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.manager.AccessManager
|
import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.provider.PermissionProvider
|
import com.gewuyou.forgeboot.security.authorize.api.core.provider.PermissionProvider
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.strategy.AuthorizationStrategy
|
import com.gewuyou.forgeboot.security.authorize.api.core.strategy.AuthorizationStrategy
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.provider
|
package com.gewuyou.forgeboot.security.authorize.impl.core.provider
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.core.extension.log
|
import com.gewuyou.forgeboot.core.extension.log
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.provider.PermissionProvider
|
import com.gewuyou.forgeboot.security.authorize.api.core.provider.PermissionProvider
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authorize.impl.core.provider
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单例 Token 认证提供者,实现 Spring Security 的 AuthenticationProvider 接口。
|
||||||
|
*
|
||||||
|
* 用于处理基于 SingleToken 的身份验证流程。
|
||||||
|
*
|
||||||
|
* @property singleTokenValidator 用于执行 Token 校验的服务组件。
|
||||||
|
* @author gewuyou
|
||||||
|
* @since 2025-06-25 13:09:43
|
||||||
|
*/
|
||||||
|
class SingleTokenAuthenticationProvider(
|
||||||
|
private val singleTokenValidator: SingleTokenValidator<SingleTokenPrincipal>
|
||||||
|
) : AuthenticationProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行身份验证操作。
|
||||||
|
*
|
||||||
|
* 将传入的身份验证对象转换为 SingleTokenAuthenticationToken 类型,
|
||||||
|
* 然后通过 singleTokenService 验证 Token 的有效性,并返回认证后的 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
|
||||||
|
|
||||||
|
// 使用 Token 的 principal 值进行校验,获取 Token 信息
|
||||||
|
val tokenInfo = singleTokenValidator.validate(token.principal.toString())
|
||||||
|
|
||||||
|
// 创建已认证的 Authentication 实例并返回
|
||||||
|
return SingleTokenAuthenticationToken.authenticated(tokenInfo, tokenInfo.authorities)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断当前 Provider 是否支持给定的身份验证类型。
|
||||||
|
*
|
||||||
|
* 此方法检查传入的身份验证类是否是 SingleTokenAuthenticationToken 或其子类。
|
||||||
|
*
|
||||||
|
* @param authentication 要检查的身份验证类。
|
||||||
|
* @return 如果支持该类型则返回 true,否则返回 false。
|
||||||
|
*/
|
||||||
|
override fun supports(authentication: Class<*>): Boolean {
|
||||||
|
// 检查传入的身份验证类是否是 SingleTokenAuthenticationToken 或其子类
|
||||||
|
return SingleTokenAuthenticationToken::class.java.isAssignableFrom(authentication)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.resolver
|
package com.gewuyou.forgeboot.security.authorize.impl.core.resolver
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver
|
import com.gewuyou.forgeboot.security.authorize.api.core.resolver.PermissionResolver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认权限解析程序
|
* 默认权限解析程序
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.resolver
|
package com.gewuyou.forgeboot.security.authorize.impl.core.resolver
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory
|
||||||
import org.springframework.context.expression.BeanFactoryResolver
|
import org.springframework.context.expression.BeanFactoryResolver
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.strategy
|
package com.gewuyou.forgeboot.security.authorize.impl.core.strategy
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.provider.PermissionProvider
|
import com.gewuyou.forgeboot.security.authorize.api.core.provider.PermissionProvider
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.strategy.AuthorizationStrategy
|
import com.gewuyou.forgeboot.security.authorize.api.core.strategy.AuthorizationStrategy
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1,10 +1,10 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.adapter
|
package com.gewuyou.forgeboot.security.authorize.impl.servlet.adapter
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.core.extension.log
|
import com.gewuyou.forgeboot.core.extension.log
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.manager.AccessManager
|
import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver
|
import com.gewuyou.forgeboot.security.authorize.api.core.resolver.PermissionResolver
|
||||||
|
import com.gewuyou.forgeboot.security.authorize.api.servlet.manager.DynamicAuthorizationManager
|
||||||
import org.springframework.security.authorization.AuthorizationDecision
|
import org.springframework.security.authorization.AuthorizationDecision
|
||||||
import org.springframework.security.authorization.AuthorizationManager
|
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.security.web.access.intercept.RequestAuthorizationContext
|
import org.springframework.security.web.access.intercept.RequestAuthorizationContext
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
@ -20,7 +20,7 @@ import java.util.function.Supplier
|
|||||||
class DynamicAuthorizationManagerAdapter(
|
class DynamicAuthorizationManagerAdapter(
|
||||||
private val accessManager: AccessManager,
|
private val accessManager: AccessManager,
|
||||||
private val permissionResolver: PermissionResolver,
|
private val permissionResolver: PermissionResolver,
|
||||||
) : AuthorizationManager<RequestAuthorizationContext> {
|
) : DynamicAuthorizationManager<RequestAuthorizationContext> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行权限校验的核心方法。
|
* 执行权限校验的核心方法。
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authorize.impl.servlet.customizer
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.constants.SecurityConstants
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.customizer.HttpSecurityCustomizer
|
||||||
|
import jakarta.servlet.Filter
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于单 Token 认证的安全配置定制器
|
||||||
|
*
|
||||||
|
* 该类用于在 Spring Security 的过滤器链中注册并配置 API 密钥身份验证逻辑,
|
||||||
|
* 仅当当前安全链标识符匹配 SINGLE_TOKEN_CHAIN_ID 时生效。
|
||||||
|
*
|
||||||
|
* @property singleTokenAuthenticationFilter 处理 API 密钥身份验证请求的过滤器实例
|
||||||
|
* @since 2025-06-25 16:09:38
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
class SingleTokenHttpSecurityCustomizer(
|
||||||
|
private val singleTokenAuthenticationFilter: Filter
|
||||||
|
) : HttpSecurityCustomizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断当前定制器是否支持处理指定的安全链配置
|
||||||
|
*
|
||||||
|
* 此方法用于标识该定制器是否适用于特定的安全链配置。
|
||||||
|
* 实现类应根据 chainId 参数决定是否启用此定制器的逻辑。
|
||||||
|
*
|
||||||
|
* @param chainId 安全链的唯一标识符,用于区分不同的安全配置场景
|
||||||
|
* @return Boolean 返回 true 表示支持该 chainId,否则不支持
|
||||||
|
*/
|
||||||
|
override fun supports(chainId: String): Boolean {
|
||||||
|
return SecurityConstants.SINGLE_TOKEN_CHAIN_ID == chainId
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行安全配置的定制逻辑
|
||||||
|
*
|
||||||
|
* 将 API 密钥身份验证过滤器添加到 Spring Security 的过滤器链中,
|
||||||
|
* 置于 UsernamePasswordAuthenticationFilter 之前以确保优先处理 Token 请求。
|
||||||
|
*
|
||||||
|
* @param http 用于构建 HTTP 安全策略的 HttpSecurity 实例
|
||||||
|
* 通过此参数可添加或修改安全规则,如认证、授权等
|
||||||
|
*/
|
||||||
|
override fun customize(http: HttpSecurity) {
|
||||||
|
// 配置安全逻辑:注册认证提供者并将 API 密钥过滤器插入到过滤器链中的合适位置
|
||||||
|
http
|
||||||
|
.addFilterBefore(singleTokenAuthenticationFilter, UsernamePasswordAuthenticationFilter::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authorize.impl.servlet.filter
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.constants.SecurityConstants
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.token.SingleTokenAuthenticationToken
|
||||||
|
import jakarta.servlet.FilterChain
|
||||||
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
|
import jakarta.servlet.http.HttpServletResponse
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单Token认证过滤器
|
||||||
|
*
|
||||||
|
* 用于在请求处理链中执行基于Token的身份验证逻辑。
|
||||||
|
* 从请求头中提取指定格式的Token并构造未认证身份令牌放入安全上下文。
|
||||||
|
*
|
||||||
|
* @since 2025-06-25 13:34:47
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
class SingleTokenAuthenticationFilter() : OncePerRequestFilter() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行内部过滤逻辑
|
||||||
|
*
|
||||||
|
* 从请求头中提取API密钥,解析出Token后构造未认证的SingleTokenAuthenticationToken,
|
||||||
|
* 并将其设置到SecurityContextHolder上下文中。若当前上下文已存在认证信息,则直接跳过。
|
||||||
|
*
|
||||||
|
* @param request 当前HTTP请求
|
||||||
|
* @param response 当前HTTP响应
|
||||||
|
* @param chain 过滤器链,用于继续执行后续的过滤操作
|
||||||
|
*/
|
||||||
|
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) {
|
||||||
|
// 如果已有认证信息,跳过
|
||||||
|
if (SecurityContextHolder.getContext().authentication != null) {
|
||||||
|
chain.doFilter(request, response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val header = request.getHeader(SecurityConstants.AUTHORIZATION_HEADER)
|
||||||
|
if (header?.startsWith(SecurityConstants.BEARER_PREFIX) == true) {
|
||||||
|
val token = header.removePrefix(SecurityConstants.BEARER_PREFIX).trim()
|
||||||
|
// 构造未认证的 token 放入上下文
|
||||||
|
val authentication = SingleTokenAuthenticationToken.unauthenticated(token)
|
||||||
|
SecurityContextHolder.getContext().authentication = authentication
|
||||||
|
}
|
||||||
|
chain.doFilter(request, response)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.handler
|
package com.gewuyou.forgeboot.security.authorize.impl.servlet.handler
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import com.gewuyou.forgeboot.core.extension.log
|
import com.gewuyou.forgeboot.core.extension.log
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.config.SecurityAuthorizeProperties
|
import com.gewuyou.forgeboot.security.authorize.api.core.config.SecurityAuthorizeProperties
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.R
|
import com.gewuyou.forgeboot.webmvc.dto.R
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import jakarta.servlet.http.HttpServletResponse
|
import jakarta.servlet.http.HttpServletResponse
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.builder
|
package com.gewuyou.forgeboot.security.authorize.impl.servlet.registrar
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.core.common.builder.SecurityFilterChainRegistrar
|
|
||||||
import com.gewuyou.forgeboot.security.core.common.customizer.HttpSecurityCustomizer
|
import com.gewuyou.forgeboot.security.core.common.customizer.HttpSecurityCustomizer
|
||||||
import com.gewuyou.forgeboot.security.core.common.extension.cleanUnNeedConfig
|
import com.gewuyou.forgeboot.security.core.common.extension.cleanUnNeedConfig
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.registrar.SecurityFilterChainRegistrar
|
||||||
import com.gewuyou.forgeboot.security.core.common.wrapper.SecurityFilterChainWrapper
|
import com.gewuyou.forgeboot.security.core.common.wrapper.SecurityFilterChainWrapper
|
||||||
import org.springframework.http.HttpMethod
|
import org.springframework.http.HttpMethod
|
||||||
import org.springframework.security.authorization.AuthorizationManager
|
import org.springframework.security.authorization.AuthorizationManager
|
||||||
@ -45,7 +45,7 @@ class StatelessSecurityFilterChainRegistrar(
|
|||||||
matcher: RequestMatcher,
|
matcher: RequestMatcher,
|
||||||
config: (HttpSecurity) -> Unit,
|
config: (HttpSecurity) -> Unit,
|
||||||
): SecurityFilterChainWrapper {
|
): SecurityFilterChainWrapper {
|
||||||
// 清除不必要的默认安全配置,优化无状态场景下的行为
|
// 清除不必要默认安全配置,优化无状态场景下的行为
|
||||||
// 设置请求匹配器以确定过滤器链适用范围
|
// 设置请求匹配器以确定过滤器链适用范围
|
||||||
// 配置 HTTP 请求的授权规则:
|
// 配置 HTTP 请求的授权规则:
|
||||||
// - 允许所有 OPTIONS 请求(通常用于跨域预检)
|
// - 允许所有 OPTIONS 请求(通常用于跨域预检)
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.adapter
|
package com.gewuyou.forgeboot.security.authorize.impl.webflux.adapter
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.manager.AccessManager
|
import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.manager.DynamicReactiveAuthorizationManager
|
import com.gewuyou.forgeboot.security.authorize.api.webflux.manager.DynamicReactiveAuthorizationManager
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver
|
import com.gewuyou.forgeboot.security.authorize.api.core.resolver.PermissionResolver
|
||||||
import org.springframework.security.authorization.AuthorizationDecision
|
import org.springframework.security.authorization.AuthorizationDecision
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.security.web.server.authorization.AuthorizationContext
|
import org.springframework.security.web.server.authorization.AuthorizationContext
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authorize.impl.webflux.customizer
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.constants.SecurityConstants
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.customizer.ServerHttpSecurityCustomizer
|
||||||
|
import org.springframework.security.config.web.server.SecurityWebFiltersOrder
|
||||||
|
import org.springframework.security.config.web.server.ServerHttpSecurity
|
||||||
|
import org.springframework.web.server.WebFilter
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于在 Spring WebFlux 环境下进行基于 Token 的认证安全配置定制。
|
||||||
|
*
|
||||||
|
* 此类实现 ServerHttpSecurityCustomizer 接口,负责将自定义的 Token 认证逻辑集成到安全链中。
|
||||||
|
* 它通过 supports 方法判断是否适用于当前的安全链配置,并通过 customize 方法插入过滤器。
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param reactiveSingleTokenAuthenticationFilter 自定义的 WebFilter 实现,用于执行 Token 认证逻辑
|
||||||
|
*/
|
||||||
|
class SingleTokenServerHttpSecurityCustomizer(
|
||||||
|
private val reactiveSingleTokenAuthenticationFilter: WebFilter,
|
||||||
|
) : ServerHttpSecurityCustomizer {
|
||||||
|
/**
|
||||||
|
* 判断当前定制器是否支持处理指定的安全链配置。
|
||||||
|
*
|
||||||
|
* 该方法用于标识此定制器是否适用于给定 chainId 所代表的安全配置场景。
|
||||||
|
* 在本实现中,仅当 chainId 与预定义的 SINGLE_TOKEN_CHAIN_ID 匹配时返回 true。
|
||||||
|
*
|
||||||
|
* @param chainId 安全链的唯一标识符,用于区分不同的安全配置场景
|
||||||
|
* @return Boolean 返回 true 表示支持该 chainId,否则不支持
|
||||||
|
*/
|
||||||
|
override fun supports(chainId: String): Boolean {
|
||||||
|
return SecurityConstants.SINGLE_TOKEN_CHAIN_ID == chainId
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义 ServerHttpSecurity 配置的方法。
|
||||||
|
*
|
||||||
|
* 此方法由框架调用,允许开发者插入特定于该安全链的配置逻辑。
|
||||||
|
* 参数提供了 ServerHttpSecurity 实例,可以通过其添加、修改或删除安全相关的组件。
|
||||||
|
*
|
||||||
|
* @param http ServerHttpSecurity 实例,用于构建 WebFlux 安全配置
|
||||||
|
*/
|
||||||
|
override fun customize(http: ServerHttpSecurity) {
|
||||||
|
// 将 Token 认证过滤器添加到 WebFlux 安全链中的认证位置
|
||||||
|
http.addFilterAt(reactiveSingleTokenAuthenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.authorize.impl.webflux.filter
|
||||||
|
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.constants.SecurityConstants
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.token.SingleTokenAuthenticationToken
|
||||||
|
import org.springframework.http.HttpHeaders
|
||||||
|
import org.springframework.security.authentication.ReactiveAuthenticationManager
|
||||||
|
import org.springframework.security.core.Authentication
|
||||||
|
import org.springframework.security.web.server.authentication.AuthenticationWebFilter
|
||||||
|
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter
|
||||||
|
import org.springframework.web.server.ServerWebExchange
|
||||||
|
import reactor.core.publisher.Mono
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 反应式单令牌身份验证过滤器
|
||||||
|
*
|
||||||
|
* 用于在 WebFlux 环境下通过单 Token 进行身份验证的过滤器。
|
||||||
|
* 它继承自 [AuthenticationWebFilter],并使用 [SingleTokenServerAuthenticationConverter]
|
||||||
|
* 将请求中的 Token 转换为认证对象 [SingleTokenAuthenticationToken]。
|
||||||
|
*
|
||||||
|
* @property authenticationManager 身份验证管理器,用于处理身份验证请求
|
||||||
|
* @since 2025-06-25 16:46:13
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
class ReactiveSingleTokenAuthenticationFilter(
|
||||||
|
authenticationManager: ReactiveAuthenticationManager
|
||||||
|
) : AuthenticationWebFilter(authenticationManager) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化代码块,设置当前过滤器使用的身份验证转换器。
|
||||||
|
*
|
||||||
|
* 此处将默认的转换逻辑替换为基于 Token 的身份验证转换器,
|
||||||
|
* 该转换器负责从请求头中提取并解析 Token。
|
||||||
|
*/
|
||||||
|
init {
|
||||||
|
setServerAuthenticationConverter(SingleTokenServerAuthenticationConverter())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于 Token 的身份验证转换器实现类。
|
||||||
|
*
|
||||||
|
* 实现了 [ServerAuthenticationConverter] 接口,负责从 [ServerWebExchange] 中提取 Token,
|
||||||
|
* 并将其转换为对应的认证对象 [SingleTokenAuthenticationToken]。
|
||||||
|
*/
|
||||||
|
private class SingleTokenServerAuthenticationConverter : ServerAuthenticationConverter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将传入的请求上下文转换为认证对象。
|
||||||
|
*
|
||||||
|
* 此方法尝试从请求头中获取 `Authorization` 字段,并检查其是否以指定的前缀开头。
|
||||||
|
* 如果匹配,则移除前缀并提取出 Token,最终构造一个未认证的 [SingleTokenAuthenticationToken] 对象。
|
||||||
|
*
|
||||||
|
* @param exchange 当前的服务器 Web 交换对象,包含请求信息
|
||||||
|
* @return 返回一个 [Mono<Authentication>?] 类型的对象,如果成功提取 Token 则返回包含认证对象的 Mono;
|
||||||
|
* 否则返回空的 Mono。
|
||||||
|
*/
|
||||||
|
override fun convert(exchange: ServerWebExchange): Mono<Authentication>? {
|
||||||
|
val headerValue = exchange.request.headers.getFirst(HttpHeaders.AUTHORIZATION)
|
||||||
|
return if (headerValue?.startsWith(SecurityConstants.BEARER_PREFIX, ignoreCase = true) == true) {
|
||||||
|
val singleToken = headerValue.removePrefix(SecurityConstants.BEARER_PREFIX).trim()
|
||||||
|
Mono.just(SingleTokenAuthenticationToken(singleToken, null))
|
||||||
|
} else {
|
||||||
|
Mono.empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.handler
|
package com.gewuyou.forgeboot.security.authorize.impl.webflux.handler
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import com.gewuyou.forgeboot.core.extension.log
|
import com.gewuyou.forgeboot.core.extension.log
|
||||||
import com.gewuyou.forgeboot.security.authorize.api.config.SecurityAuthorizeProperties
|
import com.gewuyou.forgeboot.security.authorize.api.core.config.SecurityAuthorizeProperties
|
||||||
import com.gewuyou.forgeboot.webmvc.dto.R
|
import com.gewuyou.forgeboot.webmvc.dto.R
|
||||||
import org.springframework.http.HttpHeaders
|
import org.springframework.http.HttpHeaders
|
||||||
import org.springframework.http.HttpStatus
|
import org.springframework.http.HttpStatus
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.gewuyou.forgeboot.security.authorize.impl.builder
|
package com.gewuyou.forgeboot.security.authorize.impl.webflux.registrar
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.core.common.builder.SecurityWebFilterChainRegistrar
|
|
||||||
import com.gewuyou.forgeboot.security.core.common.customizer.ServerHttpSecurityCustomizer
|
import com.gewuyou.forgeboot.security.core.common.customizer.ServerHttpSecurityCustomizer
|
||||||
import com.gewuyou.forgeboot.security.core.common.extension.cleanUnNeedConfig
|
import com.gewuyou.forgeboot.security.core.common.extension.cleanUnNeedConfig
|
||||||
|
import com.gewuyou.forgeboot.security.core.common.registrar.SecurityWebFilterChainRegistrar
|
||||||
import com.gewuyou.forgeboot.security.core.common.wrapper.SecurityWebFilterChainWrapper
|
import com.gewuyou.forgeboot.security.core.common.wrapper.SecurityWebFilterChainWrapper
|
||||||
import org.springframework.http.HttpMethod
|
import org.springframework.http.HttpMethod
|
||||||
import org.springframework.security.authorization.ReactiveAuthorizationManager
|
import org.springframework.security.authorization.ReactiveAuthorizationManager
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.core.authorize.entities
|
||||||
|
|
||||||
|
import org.springframework.security.core.GrantedAuthority
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API 密钥主体,用于存储认证后的API密钥相关信息。
|
||||||
|
*
|
||||||
|
* @property principal 认证主体标识,通常是API密钥字符串
|
||||||
|
* @property authorities 与此API密钥关联的权限列表
|
||||||
|
*
|
||||||
|
* @since 2025-06-25 13:11:37
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
data class SingleTokenPrincipal (
|
||||||
|
val principal: String,
|
||||||
|
val authorities: List<GrantedAuthority>
|
||||||
|
)
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.core.common.constants
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安全相关常量定义
|
||||||
|
*
|
||||||
|
* 该对象存储与安全认证相关的通用常量,便于统一管理和维护。
|
||||||
|
* 包含请求头字段名称、令牌前缀及链路标识等关键信息。
|
||||||
|
*
|
||||||
|
* @since 2025-06-25 16:02:05
|
||||||
|
* @author gewuyou
|
||||||
|
*/
|
||||||
|
object SecurityConstants {
|
||||||
|
/**
|
||||||
|
* HTTP请求头中用于携带身份凭证的字段名称
|
||||||
|
* 通常在请求头中使用,格式为 "Authorization: Bearer <token>"
|
||||||
|
*/
|
||||||
|
const val AUTHORIZATION_HEADER = "Authorization"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP请求头中用于携带刷新令牌的字段名称
|
||||||
|
* 用于获取新的访问令牌,避免频繁登录
|
||||||
|
*/
|
||||||
|
const val REFRESH_TOKEN_HEADER = "X-Refresh-Token"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bearer Token前缀,用于在请求头中标识Token类型
|
||||||
|
* 避免与其他类型的令牌混淆,如 Basic Auth
|
||||||
|
*/
|
||||||
|
const val BEARER_PREFIX = "Bearer "
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单一令牌模式下的链路标识
|
||||||
|
* 用于区分不同认证模式或业务场景的令牌处理逻辑
|
||||||
|
*/
|
||||||
|
const val SINGLE_TOKEN_CHAIN_ID = "singleToken"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认的API密钥标识
|
||||||
|
* 用于未指定具体链路时的默认认证方式
|
||||||
|
*/
|
||||||
|
const val DEFAULT_CHAIN_ID = "default"
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.security.core.common.builder
|
package com.gewuyou.forgeboot.security.core.common.registrar
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.core.common.wrapper.SecurityFilterChainWrapper
|
import com.gewuyou.forgeboot.security.core.common.wrapper.SecurityFilterChainWrapper
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.gewuyou.forgeboot.security.core.common.builder
|
package com.gewuyou.forgeboot.security.core.common.registrar
|
||||||
|
|
||||||
import com.gewuyou.forgeboot.security.core.common.wrapper.SecurityWebFilterChainWrapper
|
import com.gewuyou.forgeboot.security.core.common.wrapper.SecurityWebFilterChainWrapper
|
||||||
import org.springframework.security.config.web.server.ServerHttpSecurity
|
import org.springframework.security.config.web.server.ServerHttpSecurity
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
package com.gewuyou.forgeboot.security.core.common.token
|
||||||
|
|
||||||
|
import org.springframework.security.authentication.AbstractAuthenticationToken
|
||||||
|
import org.springframework.security.core.GrantedAuthority
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于单令牌认证的认证令牌实现类。该类扩展了 Spring Security 的 AbstractAuthenticationToken,
|
||||||
|
* 用于表示基于单一令牌(如 API Key)的认证请求。
|
||||||
|
*
|
||||||
|
* @param principal 表示经过认证的主体,可以是用户对象或其他形式的身份标识,不可为 null。
|
||||||
|
* @param authorities 用户所拥有的权限集合,默认为空列表。
|
||||||
|
*
|
||||||
|
* @author gewuyou
|
||||||
|
* @since 2025-06-25 13:06:54
|
||||||
|
*/
|
||||||
|
class SingleTokenAuthenticationToken(
|
||||||
|
private val principal: Any,
|
||||||
|
authorities: Collection<GrantedAuthority>? = null,
|
||||||
|
) : AbstractAuthenticationToken(authorities) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化方法,根据是否提供权限信息设置认证状态。
|
||||||
|
* 如果权限信息为 null,则认证状态设为未认证;否则设为已认证。
|
||||||
|
*/
|
||||||
|
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<GrantedAuthority>,
|
||||||
|
): SingleTokenAuthenticationToken {
|
||||||
|
return SingleTokenAuthenticationToken(principal.toString(), authorities)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取认证凭据。对于单令牌认证来说,凭证通常不适用,因此返回 null。
|
||||||
|
*
|
||||||
|
* @return 始终返回 null。
|
||||||
|
*/
|
||||||
|
override fun getCredentials(): Any? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取认证的主体信息。
|
||||||
|
*
|
||||||
|
* @return 返回认证的主体对象。
|
||||||
|
*/
|
||||||
|
override fun getPrincipal(): Any = principal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 禁止直接设置认证状态。应使用工厂方法创建已认证或未认证的实例。
|
||||||
|
*
|
||||||
|
* @param authenticated 认证状态,此参数将被忽略。
|
||||||
|
* @throws IllegalArgumentException 总是抛出此异常以防止直接修改认证状态。
|
||||||
|
*/
|
||||||
|
override fun setAuthenticated(authenticated: Boolean) {
|
||||||
|
throw IllegalArgumentException("请使用 factory 方法设置认证状态")
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user