diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/config/SecurityAuthorizeProperties.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/config/SecurityAuthorizeProperties.kt deleted file mode 100644 index a8c799a..0000000 --- a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/config/SecurityAuthorizeProperties.kt +++ /dev/null @@ -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!" -} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/annotations/RequiresPermission.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/annotations/RequiresPermission.kt similarity index 88% rename from forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/annotations/RequiresPermission.kt rename to forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/annotations/RequiresPermission.kt index 2f14492..7a33b90 100644 --- a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/annotations/RequiresPermission.kt +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/annotations/RequiresPermission.kt @@ -1,4 +1,4 @@ -package com.gewuyou.forgeboot.security.authorize.api.annotations +package com.gewuyou.forgeboot.security.authorize.api.core.annotations /** * 权限校验注解,用于标记需要特定权限才能访问的方法 diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/config/SecurityAuthorizeProperties.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/config/SecurityAuthorizeProperties.kt new file mode 100644 index 0000000..a5c6ef8 --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/config/SecurityAuthorizeProperties.kt @@ -0,0 +1,42 @@ +package com.gewuyou.forgeboot.security.authorize.api.core.config + +import org.springframework.boot.context.properties.ConfigurationProperties + +/** + * Security 授权配置属性类,用于定义安全相关的可配置项 + * + * 该类通过@ConfigurationProperties绑定配置前缀"forgeboot.security.authorize", + * 提供了默认异常响应消息和API密钥启用状态的配置支持。 + * + * @property defaultExceptionResponse 当访问被拒绝时返回的默认提示信息 + * @property apiKey API密钥相关配置属性对象 + * + * @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!" + + /** + * API密钥相关配置属性对象,包含是否启用API密钥验证的开关 + */ + var apiKey: ApiKeyProperties = ApiKeyProperties() + + /** + * API密钥功能的子配置类,用于控制API密钥验证的启用状态 + * + * @property enabled 是否启用API密钥验证功能,默认为false + */ + class ApiKeyProperties { + /** + * 控制是否启用API密钥验证功能,默认值为false + */ + var enabled: Boolean = false + var pathPatterns: List = listOf("/api/**") + var useAuthorizationManager: Boolean = true + } +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/manager/AccessManager.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/manager/AccessManager.kt similarity index 88% rename from forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/manager/AccessManager.kt rename to forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/manager/AccessManager.kt index 534f2c4..129521b 100644 --- a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/manager/AccessManager.kt +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/manager/AccessManager.kt @@ -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 @@ -17,4 +17,4 @@ fun interface AccessManager { * @return Boolean 返回是否有权限的布尔值 */ fun hasPermission(authentication: Authentication, permission: String): Boolean -} +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/provider/PermissionProvider.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/provider/PermissionProvider.kt similarity index 88% rename from forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/provider/PermissionProvider.kt rename to forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/provider/PermissionProvider.kt index b152c79..2b258bd 100644 --- a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/provider/PermissionProvider.kt +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/provider/PermissionProvider.kt @@ -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 diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/resolver/PermissionResolver.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/resolver/PermissionResolver.kt similarity index 91% rename from forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/resolver/PermissionResolver.kt rename to forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/resolver/PermissionResolver.kt index 2b14e0c..4484498 100644 --- a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/resolver/PermissionResolver.kt +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/resolver/PermissionResolver.kt @@ -1,4 +1,4 @@ -package com.gewuyou.forgeboot.security.authorize.api.resolver +package com.gewuyou.forgeboot.security.authorize.api.core.resolver /** * 权限解析程序接口,用于将请求路径和HTTP方法转换为具体的权限标识符。 diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/service/ApiKeyService.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/service/ApiKeyService.kt new file mode 100644 index 0000000..37effd0 --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/service/ApiKeyService.kt @@ -0,0 +1,13 @@ +package com.gewuyou.forgeboot.security.authorize.api.core.service + +import com.gewuyou.forgeboot.security.core.authorize.entities.ApiKeyPrincipal + +/** + *API 密钥服务 + * + * @since 2025-06-25 13:10:38 + * @author gewuyou + */ +fun interface ApiKeyService { + fun validate(apiKey: String): ApiKeyPrincipal // 负责验证与解析 +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/strategy/AuthorizationStrategy.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/strategy/AuthorizationStrategy.kt similarity index 87% rename from forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/strategy/AuthorizationStrategy.kt rename to forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/strategy/AuthorizationStrategy.kt index c6c0c0a..91f97b6 100644 --- a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/strategy/AuthorizationStrategy.kt +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/core/strategy/AuthorizationStrategy.kt @@ -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 /** diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/manager/DynamicAuthorizationManager.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/servlet/manager/DynamicAuthorizationManager.kt similarity index 88% rename from forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/manager/DynamicAuthorizationManager.kt rename to forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/servlet/manager/DynamicAuthorizationManager.kt index cfaf1a9..8f36cab 100644 --- a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/manager/DynamicAuthorizationManager.kt +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/servlet/manager/DynamicAuthorizationManager.kt @@ -1,16 +1,16 @@ -package com.gewuyou.forgeboot.security.authorize.api.manager +package com.gewuyou.forgeboot.security.authorize.api.servlet.manager import org.springframework.security.authorization.AuthorizationManager /** * 动态授权管理器接口 - * + * * 该接口用于处理请求级别的动态权限控制逻辑,基于Spring Security的AuthorizationManager接口进行扩展。 * 通过泛型类型T定义需要处理的授权上下文类型,例如Web请求或方法调用等。 * * @param 授权操作涉及的具体上下文类型,如RequestAuthorizationContext或其他自定义上下文对象 - * + * * @since 2025-06-24 15:52:01 * @author gewuyou */ -interface DynamicAuthorizationManager : AuthorizationManager +interface DynamicAuthorizationManager : AuthorizationManager \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/manager/DynamicReactiveAuthorizationManager.kt b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/webflux/manager/DynamicReactiveAuthorizationManager.kt similarity index 79% rename from forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/manager/DynamicReactiveAuthorizationManager.kt rename to forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/webflux/manager/DynamicReactiveAuthorizationManager.kt index e1dbfde..a8eba35 100644 --- a/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/manager/DynamicReactiveAuthorizationManager.kt +++ b/forgeboot-security/forgeboot-security-authorize/api/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/api/webflux/manager/DynamicReactiveAuthorizationManager.kt @@ -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 diff --git a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ForgeSecurityAuthorizeAutoConfiguration.kt b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ForgeSecurityAuthorizeAutoConfiguration.kt index ee9f363..1d418e3 100644 --- a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ForgeSecurityAuthorizeAutoConfiguration.kt +++ b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ForgeSecurityAuthorizeAutoConfiguration.kt @@ -1,6 +1,6 @@ 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.context.annotation.Configuration diff --git a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/core/ApiKeySecurityCoreAutoConfiguration.kt b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/core/ApiKeySecurityCoreAutoConfiguration.kt new file mode 100644 index 0000000..c5d20dd --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/core/ApiKeySecurityCoreAutoConfiguration.kt @@ -0,0 +1,58 @@ +package com.gewuyou.forgeboot.security.authorize.autoconfigure.core + +import com.gewuyou.forgeboot.security.authorize.api.core.service.ApiKeyService +import com.gewuyou.forgeboot.security.authorize.impl.core.provider.ApiKeyAuthenticationProvider +import com.gewuyou.forgeboot.security.core.authorize.entities.ApiKeyPrincipal +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 + +/** + * API 密钥安全核心自动配置类。 + * + * 该配置类用于注册与 API 密钥相关的 Bean,确保在 Spring 容器中存在必要的服务和认证提供者。 + * 主要作用包括: + * - 提供默认的 ApiKeyService Bean(未实现时)。 + * - 提供 ApiKeyAuthenticationProvider Bean 以支持基于 API 密钥的身份验证。 + * + * @since 2025-06-25 15:49:50 + * @author gewuyou + */ +@Configuration(proxyBeanMethods = false) +class ApiKeySecurityCoreAutoConfiguration { + + /** + * 提供一个默认的 ApiKeyService Bean 实现。 + * + * 如果容器中不存在 ApiKeyService 的实现,则会使用此默认 Bean。 + * 默认实现的 validate 方法始终抛出 UnsupportedOperationException, + * 提示用户需要自定义并注册自己的 ApiKeyService 实现。 + * + * @return 返回一个未实现的 ApiKeyService 对象 + */ + @Bean + @ConditionalOnMissingBean + fun apiKeyService(): ApiKeyService { + return object : ApiKeyService { + override fun validate(apiKey: String): ApiKeyPrincipal { + throw UnsupportedOperationException("请提供 ApiKeyService 实现") + } + } + } + + /** + * 提供一个用于认证的 ApiKeyAuthenticationProvider Bean。 + * + * 如果容器中尚不存在同名 Bean,则创建并返回 ApiKeyAuthenticationProvider 实例。 + * 该 Provider 使用传入的 apiKeyService 来处理具体的 API 密钥验证逻辑。 + * + * @param apiKeyService 用于处理 API 密钥逻辑的服务实现 + * @return AuthenticationProvider 的具体实现对象 + */ + @Bean("apiKeyAuthenticationProvider") + @ConditionalOnMissingBean + fun apiKeyAuthenticationProvider(apiKeyService: ApiKeyService): AuthenticationProvider { + return ApiKeyAuthenticationProvider(apiKeyService) + } +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ForgeSecurityAuthorizeCoreConfiguration.kt b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/core/ForgeSecurityAuthorizeCoreConfiguration.kt similarity index 79% rename from forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ForgeSecurityAuthorizeCoreConfiguration.kt rename to forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/core/ForgeSecurityAuthorizeCoreConfiguration.kt index 63c712b..481f1d9 100644 --- a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ForgeSecurityAuthorizeCoreConfiguration.kt +++ b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/core/ForgeSecurityAuthorizeCoreConfiguration.kt @@ -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.provider.PermissionProvider -import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver -import com.gewuyou.forgeboot.security.authorize.api.strategy.AuthorizationStrategy -import com.gewuyou.forgeboot.security.authorize.impl.manager.DefaultAccessManager -import com.gewuyou.forgeboot.security.authorize.impl.resolver.DefaultPermissionResolver -import com.gewuyou.forgeboot.security.authorize.impl.strategy.AnyMatchStrategy +import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager +import com.gewuyou.forgeboot.security.authorize.api.core.provider.PermissionProvider +import com.gewuyou.forgeboot.security.authorize.api.core.resolver.PermissionResolver +import com.gewuyou.forgeboot.security.authorize.api.core.strategy.AuthorizationStrategy +import com.gewuyou.forgeboot.security.authorize.impl.core.manager.DefaultAccessManager +import com.gewuyou.forgeboot.security.authorize.impl.core.resolver.DefaultPermissionResolver +import com.gewuyou.forgeboot.security.authorize.impl.core.strategy.AnyMatchStrategy import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -20,7 +20,7 @@ import org.springframework.context.annotation.Configuration * @since 2025-06-24 16:49:37 * @author gewuyou */ -@Configuration +@Configuration(proxyBeanMethods = false) class ForgeSecurityAuthorizeCoreConfiguration { /** * 权限解析器Bean,用于将权限表达式解析为具体的权限对象。 diff --git a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/servlet/ServletApiKeySecurityAutoConfiguration.kt b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/servlet/ServletApiKeySecurityAutoConfiguration.kt new file mode 100644 index 0000000..84b946b --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/servlet/ServletApiKeySecurityAutoConfiguration.kt @@ -0,0 +1,127 @@ +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.ApiKeyHttpSecurityCustomizer +import com.gewuyou.forgeboot.security.authorize.impl.servlet.filter.ApiKeyAuthenticationFilter +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.authentication.AuthenticationManager +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 + +/** + * API 密钥安全自动配置类,用于在 Servlet Web 应用中自动装配与 API 密钥相关的安全组件。 + * + * 此配置仅在以下条件下生效: + * 1. 应用类型为 Servlet; + * 2. 配置项 "forgeboot.security.authorize.api-key.enabled" 为 true。 + * + * @property securityAuthorizeProperties 安全授权配置属性,用于获取 API 密钥相关路径等信息 + * @since 2025-06-25 13:41:56 + * @author gewuyou + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) +@ConditionalOnProperty( + prefix = "forgeboot.security.authorize.api-key", + name = ["enabled"], + havingValue = "true", + matchIfMissing = false +) +class ServletApiKeySecurityAutoConfiguration( + private val securityAuthorizeProperties: SecurityAuthorizeProperties, +) { + /** + * 创建 API 密钥认证过滤器 Bean。 + * + * 该方法在 Spring 容器中尚不存在同名 Bean 的情况下, + * 构建一个使用指定认证管理器的 ApiKeyAuthenticationFilter 实例。 + * + * @param authenticationManager 认证管理器,用于执行认证逻辑 + * @return 返回构建完成的 ApiKeyAuthenticationFilter 实例 + */ + @Bean + @ConditionalOnMissingBean(name = ["apiKeyAuthenticationFilter"]) + fun apiKeyAuthenticationFilter( + authenticationManager: AuthenticationManager, + ): Filter { + return ApiKeyAuthenticationFilter(authenticationManager) + } + + /** + * 提供一个用于自定义 HTTP 安全配置的 API 密钥安全自定义器 Bean。 + * + * 如果容器中尚不存在同名 Bean,则创建并返回 ApiKeyHttpSecurityCustomizer 实例。 + * 此自定义器将注入的认证提供者和过滤器用于构建定制化的安全配置。 + * + * @param apiKeyAuthenticationProvider 注入已配置的认证提供者,用于安全链构建 + * @param apiKeyAuthenticationFilter 注入已配置的认证过滤器,用于请求处理 + * @return 返回 HttpSecurityCustomizer 的具体实现对象 + */ + @Bean + @ConditionalOnMissingBean + fun apiKeyHttpSecurityCustomizer( + @Qualifier("apiKeyAuthenticationFilter") + apiKeyAuthenticationFilter: Filter, + ): HttpSecurityCustomizer { + return ApiKeyHttpSecurityCustomizer(apiKeyAuthenticationFilter) + } + + /** + * 创建默认的安全过滤链,适用于 Servlet 编程模型。 + * + * 此方法基于配置的路径模式构建一个复合请求匹配器,并通过注册器创建对应的安全过滤链。 + * 过滤链根据配置决定是否使用授权管理器进行访问控制。 + * + * @param registrar 安全过滤链注册器,用于构建和管理过滤链 + * @param http Spring Security 的 HttpSecurity 配置对象 + * @param authorizeManager 授权管理器,用于在启用授权管理时定义访问策略 + * @return 构建完成的安全过滤链实例 + */ + @Bean(name = ["defaultApiKeySecurityFilterChain"]) + fun defaultApiKeySecurityFilterChain( + registrar: SecurityFilterChainRegistrar, + http: HttpSecurity, + authorizeManager: AuthorizationManager + ): SecurityFilterChain { + // 从配置中获取 API 密钥适用的路径模式(如:["/api/**", "/open/**"]) + val patterns = securityAuthorizeProperties.apiKey.pathPatterns + + // 将每个路径模式转换为 AntPathRequestMatcher 实例 + val matchers = patterns.map { AntPathRequestMatcher(it) } + + // 使用 OrRequestMatcher 组合所有路径匹配规则,实现多路径匹配支持 + val combinedMatcher = OrRequestMatcher(matchers) + + // 调用注册器构建安全链,指定链 ID、HttpSecurity 对象和请求匹配器 + return registrar.buildChain( + SecurityConstants.API_KEY_CHAIN_ID, + http, + combinedMatcher + ) { config -> + if (securityAuthorizeProperties.apiKey.useAuthorizationManager) { + // 启用授权管理器时,配置请求通过指定的 authorizeManager 进行访问控制 + config.authorizeHttpRequests { + it.anyRequest().access(authorizeManager) + } + } else { + // 禁用授权管理器时,要求所有请求必须经过身份验证 + config.authorizeHttpRequests { + it.anyRequest().authenticated() + } + } + } + } +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ServletAuthorizeSecurityConfiguration.kt b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/servlet/ServletAuthorizeSecurityConfiguration.kt similarity index 66% rename from forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ServletAuthorizeSecurityConfiguration.kt rename to forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/servlet/ServletAuthorizeSecurityConfiguration.kt index 00e1b88..d57fcce 100644 --- a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ServletAuthorizeSecurityConfiguration.kt +++ b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/servlet/ServletAuthorizeSecurityConfiguration.kt @@ -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.gewuyou.forgeboot.security.authorize.api.config.SecurityAuthorizeProperties -import com.gewuyou.forgeboot.security.authorize.api.manager.AccessManager -import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver -import com.gewuyou.forgeboot.security.authorize.impl.adapter.DynamicAuthorizationManagerAdapter -import com.gewuyou.forgeboot.security.authorize.impl.builder.StatelessSecurityFilterChainRegistrar -import com.gewuyou.forgeboot.security.authorize.impl.handler.AuthorizationExceptionHandler -import com.gewuyou.forgeboot.security.core.common.builder.SecurityFilterChainRegistrar +import com.gewuyou.forgeboot.security.authorize.api.core.config.SecurityAuthorizeProperties +import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager +import com.gewuyou.forgeboot.security.authorize.api.core.resolver.PermissionResolver +import com.gewuyou.forgeboot.security.authorize.impl.servlet.adapter.DynamicAuthorizationManagerAdapter +import com.gewuyou.forgeboot.security.authorize.impl.servlet.handler.AuthorizationExceptionHandler +import com.gewuyou.forgeboot.security.authorize.impl.servlet.registrar.StatelessSecurityFilterChainRegistrar +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 org.springframework.boot.autoconfigure.condition.ConditionalOnBean 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.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.config.annotation.web.builders.HttpSecurity import org.springframework.security.web.SecurityFilterChain @@ -28,11 +33,26 @@ import org.springframework.security.web.util.matcher.AnyRequestMatcher * @author gewuyou */ @Configuration(proxyBeanMethods = false) -@ConditionalOnProperty(name = ["spring.main.web-application-type"], havingValue = "servlet", matchIfMissing = true) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) class ServletAuthorizeSecurityConfiguration( private val accessManager: AccessManager, private val permissionResolver: PermissionResolver, ) { + /** + * 创建并返回一个认证管理器。 + * + * 初始化一个基于提供的认证提供者的认证管理器,用于支持多种认证方式。 + * + * @param authenticationProviders 所有可用的认证提供者列表 + * @return 返回初始化好的 AuthenticationManager 实例,具体实现为 ProviderManager + */ + @Bean + @Primary + @ConditionalOnBean + fun authenticationManager( + authenticationProviders: List, + ): AuthenticationManager = ProviderManager(authenticationProviders) + /** * 创建默认的安全过滤链,适用于 Servlet 编程模型 * @@ -42,13 +62,13 @@ class ServletAuthorizeSecurityConfiguration( * @throws Exception 构建过程中可能抛出的异常 */ @Bean(name = ["defaultSecurityFilterChain"]) - @ConditionalOnBean(SecurityFilterChainRegistrar::class) + @ConditionalOnBean @Throws(Exception::class) fun defaultSecurityFilterChain( registrar: SecurityFilterChainRegistrar, http: HttpSecurity, ): SecurityFilterChain = registrar.buildChain( - "default", + SecurityConstants.DEFAULT_CHAIN_ID, http, AnyRequestMatcher.INSTANCE ) { config -> diff --git a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/webflux/ReactiveApiKeySecurityAutoConfiguration.kt b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/webflux/ReactiveApiKeySecurityAutoConfiguration.kt new file mode 100644 index 0000000..34c65f0 --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/webflux/ReactiveApiKeySecurityAutoConfiguration.kt @@ -0,0 +1,133 @@ +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.ApiKeyServerHttpSecurityCustomizer +import com.gewuyou.forgeboot.security.authorize.impl.webflux.filter.ApiKeyReactiveAuthenticationFilter +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 + +/** + * 反应式 API 密钥安全自动配置 + * + * 该配置类负责在 WebFlux 环境下启用 API Key 认证机制。 + * 仅在满足以下条件时生效: + * - 应用类型为 REACTIVE(反应式应用) + * - 配置项 `forgeboot.security.authorize.api-key.enabled` 被设置为 true + * + * @property securityAuthorizeProperties 安全授权配置属性,用于获取 API Key 的路径匹配规则等信息 + * @since 2025-06-25 21:04:37 + * @author gewuyou + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) +@ConditionalOnProperty( + prefix = "forgeboot.security.authorize.api-key", + name = ["enabled"], + havingValue = "true", + matchIfMissing = false +) +class ReactiveApiKeySecurityAutoConfiguration( + private val securityAuthorizeProperties: SecurityAuthorizeProperties +) { + + /** + * 创建 API Key 反应式认证过滤器 Bean + * + * 该过滤器用于处理传入请求的 API Key 认证逻辑。 + * 如果容器中尚未定义名为 "apiKeyReactiveAuthenticationFilter" 的 Bean,则创建此 Bean。 + * + * @param reactiveAuthenticationManager 反应式认证管理器,用于执行认证操作 + * @return 构建完成的 WebFilter 实例 + */ + @Bean + @ConditionalOnMissingBean(name = ["apiKeyReactiveAuthenticationFilter"]) + fun apiKeyAuthenticationFilter( + reactiveAuthenticationManager: ReactiveAuthenticationManager + ): WebFilter { + return ApiKeyReactiveAuthenticationFilter(reactiveAuthenticationManager) + } + + /** + * 创建并注册 ServerHttpSecurityCustomizer 的 Bean,用于定制 API Key 安全配置。 + * + * 此方法定义了一个用于构建 Spring Security 过滤器链时插入 API Key 认证逻辑的自定义器。 + * 仅当容器中尚未存在相同类型的 Bean 时,才会创建此 Bean。 + * + * @param apiKeyReactiveAuthenticationFilter 使用指定名称从 Spring 容器中注入的 API Key 反应式认证过滤器 Bean。 + * 该过滤器负责处理实际的 API Key 认证逻辑。 + * + * @return 构建完成的 ApiKeyServerHttpSecurityCustomizer 实例,用于在安全配置中添加 API Key 相关逻辑。 + */ + @Bean + @ConditionalOnMissingBean + fun apiKeyServerHttpSecurityCustomizer( + @Qualifier("apiKeyReactiveAuthenticationFilter") + apiKeyReactiveAuthenticationFilter: WebFilter, + ): ServerHttpSecurityCustomizer { + return ApiKeyServerHttpSecurityCustomizer(apiKeyReactiveAuthenticationFilter) + } + + /** + * 创建并注册基于 API Key 认证的 WebFlux 安全过滤器链。 + * + * 该方法利用 SecurityWebFilterChainRegistrar 注册一个具有路径匹配规则的安全过滤器链, + * 仅对符合配置中指定路径模式的请求生效,并要求通过 API Key 认证。 + * + * @param registrar 用于注册和构建安全过滤器链的核心工具类,负责链的组装过程。 + * @param http Spring Security 提供的 ServerHttpSecurity 实例,用于构建 HTTP 安全配置。 + * @param reactiveAuthorizationManager 反应式授权管理器,用于在使用授权管理逻辑时提供访问控制。 + * @return 构建完成的 SecurityWebFilterChain 实例,表示定义好的安全过滤器链。 + * + * 重要逻辑说明: + * 1. patterns: 从配置中获取 API Key 的路径匹配规则; + * 2. matchers: 将每个路径转换为 ServerWebExchangeMatcher 实例; + * 3. combinedMatcher: 综合所有 matcher,生成复合的匹配规则; + * 4. buildChain: 利用 registrar 构建过滤器链,并根据 useAuthorizationManager 配置决定采用何种认证方式: + * - 若启用 authorizationManager,则通过 access 方法设置自定义的授权逻辑; + * - 否则直接要求请求必须经过认证。 + */ + @Bean(name = ["defaultApiKeySecurityWebFilterChain"]) + fun defaultApiKeySecurityWebFilterChain( + registrar: SecurityWebFilterChainRegistrar, + http: ServerHttpSecurity, + reactiveAuthorizationManager: ReactiveAuthorizationManager + ): SecurityWebFilterChain { + val patterns = securityAuthorizeProperties.apiKey.pathPatterns + val matchers = patterns.map { PathPatternParserServerWebExchangeMatcher(it) } + val combinedMatcher: ServerWebExchangeMatcher = + ServerWebExchangeMatchers.matchers(*matchers.toTypedArray()) + return registrar.buildChain( + SecurityConstants.API_KEY_CHAIN_ID, + http, + combinedMatcher + ) { config -> + if (securityAuthorizeProperties.apiKey.useAuthorizationManager) { + config.authorizeExchange { + it.anyExchange().access(reactiveAuthorizationManager) + } + } else { + config.authorizeExchange { + it.anyExchange().authenticated() + } + } + + } + } +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ReactiveAuthorizeSecurityConfiguration.kt b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/webflux/ReactiveAuthorizeSecurityConfiguration.kt similarity index 63% rename from forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ReactiveAuthorizeSecurityConfiguration.kt rename to forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/webflux/ReactiveAuthorizeSecurityConfiguration.kt index c5ce3e5..34fabc4 100644 --- a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/ReactiveAuthorizeSecurityConfiguration.kt +++ b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/autoconfigure/webflux/ReactiveAuthorizeSecurityConfiguration.kt @@ -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.gewuyou.forgeboot.security.authorize.api.config.SecurityAuthorizeProperties -import com.gewuyou.forgeboot.security.authorize.api.manager.AccessManager -import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver -import com.gewuyou.forgeboot.security.authorize.impl.adapter.DynamicReactiveAuthorizationManagerAdapter -import com.gewuyou.forgeboot.security.authorize.impl.builder.StatelessSecurityWebFilterChainRegistrar -import com.gewuyou.forgeboot.security.authorize.impl.handler.ReactiveAuthorizationExceptionHandler -import com.gewuyou.forgeboot.security.core.common.builder.SecurityWebFilterChainRegistrar +import com.gewuyou.forgeboot.security.authorize.api.core.config.SecurityAuthorizeProperties +import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager +import com.gewuyou.forgeboot.security.authorize.api.core.resolver.PermissionResolver +import com.gewuyou.forgeboot.security.authorize.impl.webflux.adapter.DynamicReactiveAuthorizationManagerAdapter +import com.gewuyou.forgeboot.security.authorize.impl.webflux.handler.ReactiveAuthorizationExceptionHandler +import com.gewuyou.forgeboot.security.authorize.impl.webflux.registrar.StatelessSecurityWebFilterChainRegistrar +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.boot.autoconfigure.condition.ConditionalOnBean 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.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.config.annotation.web.reactive.EnableWebFluxSecurity 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.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) @EnableWebFluxSecurity -@ConditionalOnProperty(name = ["spring.main.web-application-type"], havingValue = "reactive") +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) class ReactiveAuthorizeSecurityConfiguration( private val accessManager: AccessManager, private val permissionResolver: PermissionResolver, @@ -54,9 +60,9 @@ class ReactiveAuthorizeSecurityConfiguration( http: ServerHttpSecurity, ): SecurityWebFilterChain = registrar .buildChain( - "default", + SecurityConstants.DEFAULT_CHAIN_ID, http, - anyExchange() + ServerWebExchangeMatchers.anyExchange() ) { it: ServerHttpSecurity -> it.authorizeExchange { it.anyExchange().denyAll() @@ -93,6 +99,31 @@ class ReactiveAuthorizeSecurityConfiguration( return DynamicReactiveAuthorizationManagerAdapter(accessManager, permissionResolver) } + /** + * 反应式认证管理器 + * 创建并返回一个主认证管理器实例,用于处理响应式编程环境中的身份验证请求。 + * 该管理器基于提供的认证提供者列表进行初始化。 + * + * 此方法通过将传统的 ProviderManager 包装在 ReactiveAuthenticationManagerAdapter 中, + * 实现了对响应式编程模型的支持。ProviderManager 被构造为使用给定的认证提供者列表, + * 并作为适配器的一部分来完成异步的身份验证逻辑。 + * + * @param authenticationProviders 认证提供者列表,用于执行具体的身份验证逻辑。 + * 每个提供者负责特定类型的身份验证机制。 + * @return 初始化后的 ReactiveAuthenticationManager 实例,用于响应式环境下的身份验证流程。 + * 返回的对象是 ReactiveAuthenticationManagerAdapter 的实例,其内部封装了同步的 ProviderManager。 + */ + @Bean + @Primary + @ConditionalOnBean + fun reactiveAuthenticationManager( + authenticationProviders: List + ): ReactiveAuthenticationManager { + return ReactiveAuthenticationManagerAdapter( + ProviderManager(authenticationProviders) + ) + } + /** * 无状态安全过滤链注册器 * 创建并返回一个无状态的安全过滤链注册器,用于注册需要无状态处理的安全过滤链。 diff --git a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 419994e..4a6b51e 100644 --- a/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/forgeboot-security/forgeboot-security-authorize/autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -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.ServletAuthorizeSecurityConfiguration +com.gewuyou.forgeboot.security.authorize.autoconfigure.core.ForgeSecurityAuthorizeCoreConfiguration +com.gewuyou.forgeboot.security.authorize.autoconfigure.core.ApiKeySecurityCoreAutoConfiguration +com.gewuyou.forgeboot.security.authorize.autoconfigure.webflux.ReactiveAuthorizeSecurityConfiguration +com.gewuyou.forgeboot.security.authorize.autoconfigure.webflux.ReactiveApiKeySecurityAutoConfiguration +com.gewuyou.forgeboot.security.authorize.autoconfigure.servlet.ServletAuthorizeSecurityConfiguration +com.gewuyou.forgeboot.security.authorize.autoconfigure.servlet.ServletApiKeySecurityAutoConfiguration diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/aspect/RequiresPermissionAspect.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/aspect/RequiresPermissionAspect.kt similarity index 89% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/aspect/RequiresPermissionAspect.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/aspect/RequiresPermissionAspect.kt index d39949d..54557d7 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/aspect/RequiresPermissionAspect.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/aspect/RequiresPermissionAspect.kt @@ -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.manager.AccessManager -import com.gewuyou.forgeboot.security.authorize.api.strategy.AuthorizationStrategy -import com.gewuyou.forgeboot.security.authorize.impl.resolver.SpELResolver +import com.gewuyou.forgeboot.security.authorize.api.core.annotations.RequiresPermission +import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager +import com.gewuyou.forgeboot.security.authorize.api.core.strategy.AuthorizationStrategy +import com.gewuyou.forgeboot.security.authorize.impl.core.resolver.SpELResolver import org.aspectj.lang.ProceedingJoinPoint import org.aspectj.lang.annotation.Around import org.aspectj.lang.annotation.Aspect diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/manager/DefaultAccessManager.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/manager/DefaultAccessManager.kt similarity index 68% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/manager/DefaultAccessManager.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/manager/DefaultAccessManager.kt index 3ea7eb8..54a4749 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/manager/DefaultAccessManager.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/manager/DefaultAccessManager.kt @@ -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.provider.PermissionProvider -import com.gewuyou.forgeboot.security.authorize.api.strategy.AuthorizationStrategy +import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager +import com.gewuyou.forgeboot.security.authorize.api.core.provider.PermissionProvider +import com.gewuyou.forgeboot.security.authorize.api.core.strategy.AuthorizationStrategy import org.springframework.security.core.Authentication /** diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/provider/AbstractPermissionProvider.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/provider/AbstractPermissionProvider.kt similarity index 86% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/provider/AbstractPermissionProvider.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/provider/AbstractPermissionProvider.kt index bdc06cf..f049f5e 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/provider/AbstractPermissionProvider.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/provider/AbstractPermissionProvider.kt @@ -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.security.authorize.api.provider.PermissionProvider +import com.gewuyou.forgeboot.security.authorize.api.core.provider.PermissionProvider import org.springframework.security.core.Authentication /** diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/provider/ApiKeyAuthenticationProvider.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/provider/ApiKeyAuthenticationProvider.kt new file mode 100644 index 0000000..717758a --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/provider/ApiKeyAuthenticationProvider.kt @@ -0,0 +1,57 @@ +package com.gewuyou.forgeboot.security.authorize.impl.core.provider + +import com.gewuyou.forgeboot.security.authorize.api.core.service.ApiKeyService +import com.gewuyou.forgeboot.security.core.common.token.ApiKeyAuthenticationToken +import org.springframework.security.authentication.AuthenticationProvider +import org.springframework.security.core.Authentication + +/** + * API 密钥身份验证提供程序 + * + * 该类实现 Spring Security 的 AuthenticationProvider 接口,用于处理基于 API Key 的身份验证流程。 + * + * @property apiKeyService 用于校验 API Key 并获取用户信息和权限的服务组件 + * @constructor 创建一个 ApiKeyAuthenticationProvider 实例 + * + * @since 2025-06-25 13:09:43 + * @author gewuyou + */ +class ApiKeyAuthenticationProvider( + private val apiKeyService: ApiKeyService +) : AuthenticationProvider { + + /** + * 执行身份验证操作 + * + * 将传入的 Authentication 对象转换为 ApiKeyAuthenticationToken, + * 然后使用 apiKeyService 校验 API Key 并获取相关用户信息和权限。 + * + * @param authentication 包含 API Key 的身份验证请求对象 + * @return 返回已认证的 Authentication 对象 + */ + override fun authenticate(authentication: Authentication): Authentication { + val token = authentication as ApiKeyAuthenticationToken + val keyInfo = apiKeyService.validate(token.apiKey) + + return ApiKeyAuthenticationToken( + token.apiKey, + keyInfo.principal, + keyInfo.authorities + ).apply { + isAuthenticated = true + } + } + + /** + * 判断此 Provider 是否支持给定的身份验证类型 + * + * 用于确定当前 Provider 是否可以处理指定的 Authentication 类型。 + * 此方法被调用时会检查是否为 ApiKeyAuthenticationToken 或其子类。 + * + * @param authentication 要检查的身份验证类 + * @return 如果支持则返回 true,否则返回 false + */ + override fun supports(authentication: Class<*>): Boolean { + return ApiKeyAuthenticationToken::class.java.isAssignableFrom(authentication) + } +} diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/resolver/DefaultPermissionResolver.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/resolver/DefaultPermissionResolver.kt similarity index 88% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/resolver/DefaultPermissionResolver.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/resolver/DefaultPermissionResolver.kt index acb51ba..827e32c 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/resolver/DefaultPermissionResolver.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/resolver/DefaultPermissionResolver.kt @@ -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 /** * 默认权限解析程序 diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/resolver/SpELResolver.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/resolver/SpELResolver.kt similarity index 96% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/resolver/SpELResolver.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/resolver/SpELResolver.kt index 7685458..ecb8eac 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/resolver/SpELResolver.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/resolver/SpELResolver.kt @@ -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.context.expression.BeanFactoryResolver diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/strategy/AnyMatchStrategy.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/strategy/AnyMatchStrategy.kt similarity index 78% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/strategy/AnyMatchStrategy.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/strategy/AnyMatchStrategy.kt index 308118c..82e2190 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/strategy/AnyMatchStrategy.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/core/strategy/AnyMatchStrategy.kt @@ -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.strategy.AuthorizationStrategy +import com.gewuyou.forgeboot.security.authorize.api.core.provider.PermissionProvider +import com.gewuyou.forgeboot.security.authorize.api.core.strategy.AuthorizationStrategy import org.springframework.security.core.Authentication /** diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/adapter/DynamicAuthorizationManagerAdapter.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/adapter/DynamicAuthorizationManagerAdapter.kt similarity index 83% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/adapter/DynamicAuthorizationManagerAdapter.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/adapter/DynamicAuthorizationManagerAdapter.kt index 6f44039..45bd7f4 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/adapter/DynamicAuthorizationManagerAdapter.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/adapter/DynamicAuthorizationManagerAdapter.kt @@ -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.security.authorize.api.manager.AccessManager -import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver +import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager +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.AuthorizationManager import org.springframework.security.core.Authentication import org.springframework.security.web.access.intercept.RequestAuthorizationContext import java.util.function.Supplier @@ -20,7 +20,7 @@ import java.util.function.Supplier class DynamicAuthorizationManagerAdapter( private val accessManager: AccessManager, private val permissionResolver: PermissionResolver, -) : AuthorizationManager { +) : DynamicAuthorizationManager { /** * 执行权限校验的核心方法。 diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/customizer/ApiKeyHttpSecurityCustomizer.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/customizer/ApiKeyHttpSecurityCustomizer.kt new file mode 100644 index 0000000..b9d3308 --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/customizer/ApiKeyHttpSecurityCustomizer.kt @@ -0,0 +1,55 @@ +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 + +/** + * API 密钥 HTTP 安全定制器 + * + * 用于为基于 API 密钥的身份验证机制定制 Spring Security 的 HTTP 安全配置。 + * 该类实现了 HttpSecurityCustomizer 接口,能够根据指定的安全链 ID 决定是否启用当前的认证逻辑, + * 并负责将 API 密钥身份验证过滤器和提供者注入到安全配置中。 + * + * @property apiKeyAuthenticationProvider 提供 API 密钥身份验证逻辑的认证提供者 + * @property apiKeyAuthenticationFilter 处理 API 密钥身份验证请求的过滤器实例 + * @since 2025-06-25 16:09:38 + * @author gewuyou + */ +class ApiKeyHttpSecurityCustomizer( + private val apiKeyAuthenticationFilter: Filter +) : HttpSecurityCustomizer { + + /** + * 判断当前定制器是否支持处理指定的安全链配置 + * + * 此方法用于标识该定制器是否适用于特定的安全链配置。 + * 实现类应根据 chainId 参数决定是否启用此定制器的逻辑。 + * + * @param chainId 安全链的唯一标识符,用于区分不同的安全配置场景 + * @return Boolean 返回 true 表示支持该 chainId,否则不支持 + */ + override fun supports(chainId: String): Boolean { + return SecurityConstants.API_KEY_CHAIN_ID == chainId + } + + /** + * 执行安全配置的定制逻辑 + * + * 将 API 密钥身份验证相关的组件注册到 Spring Security 流程中。 + * 包括: + * - 注册认证提供者(apiKeyAuthenticationProvider) + * - 在请求处理流程中插入 ApiKeyAuthenticationFilter 过滤器 + * 该过滤器会在 UsernamePasswordAuthenticationFilter 前执行 + * + * @param http 用于构建 HTTP 安全策略的 HttpSecurity 实例 + * 通过此参数可添加或修改安全规则,如认证、授权等 + */ + override fun customize(http: HttpSecurity) { + // 配置安全逻辑:注册认证提供者并将 API 密钥过滤器插入到过滤器链中的合适位置 + http + .addFilterBefore(apiKeyAuthenticationFilter, UsernamePasswordAuthenticationFilter::class.java) + } +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/filter/ApiKeyAuthenticationFilter.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/filter/ApiKeyAuthenticationFilter.kt new file mode 100644 index 0000000..dd7eee9 --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/filter/ApiKeyAuthenticationFilter.kt @@ -0,0 +1,51 @@ +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.ApiKeyAuthenticationToken +import jakarta.servlet.FilterChain +import jakarta.servlet.http.HttpServletRequest +import jakarta.servlet.http.HttpServletResponse +import org.springframework.security.authentication.AuthenticationManager +import org.springframework.security.core.context.SecurityContextHolder +import org.springframework.web.filter.OncePerRequestFilter + +/** + * API 密钥身份验证筛选器 + * 用于处理基于API密钥的身份验证流程,继承自OncePerRequestFilter以确保每个请求只被过滤一次。 + * + * @param authenticationManager 身份验证管理器,用于执行实际的身份验证操作 + * @since 2025-06-25 13:34:47 + * @author gewuyou + */ +class ApiKeyAuthenticationFilter( + private val authenticationManager: AuthenticationManager +) : OncePerRequestFilter() { + + /** + * 执行内部过滤逻辑 + * 从请求头中提取API密钥并进行身份验证 + * + * @param request 当前HTTP请求 + * @param response 当前HTTP响应 + * @param chain 过滤器链 + */ + override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) { + // 从请求头中获取Authorization字段 + val header = request.getHeader(SecurityConstants.AUTHORIZATION_HEADER) + + // 检查是否为Bearer类型认证信息 + if (header?.startsWith(SecurityConstants.BEARER_PREFIX) == true) { + // 提取并清理API密钥 + val apiKey = header.removePrefix(SecurityConstants.BEARER_PREFIX).trim() + + // 创建认证令牌 + val token = ApiKeyAuthenticationToken(apiKey, null) + + // 执行认证并存储认证结果到安全上下文中 + val authResult = authenticationManager.authenticate(token) + SecurityContextHolder.getContext().authentication = authResult + } + // 继续执行过滤器链 + chain.doFilter(request, response) + } +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/handler/AuthorizationExceptionHandler.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/handler/AuthorizationExceptionHandler.kt similarity index 93% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/handler/AuthorizationExceptionHandler.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/handler/AuthorizationExceptionHandler.kt index cf9af5d..99c8f5c 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/handler/AuthorizationExceptionHandler.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/handler/AuthorizationExceptionHandler.kt @@ -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.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 jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/builder/StatelessSecurityFilterChainRegistrar.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/registrar/StatelessSecurityFilterChainRegistrar.kt similarity index 93% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/builder/StatelessSecurityFilterChainRegistrar.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/registrar/StatelessSecurityFilterChainRegistrar.kt index 655e029..af0bb47 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/builder/StatelessSecurityFilterChainRegistrar.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/servlet/registrar/StatelessSecurityFilterChainRegistrar.kt @@ -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.extension.cleanUnNeedConfig +import com.gewuyou.forgeboot.security.core.common.registrar.SecurityFilterChainRegistrar import com.gewuyou.forgeboot.security.core.common.wrapper.SecurityFilterChainWrapper import org.springframework.http.HttpMethod import org.springframework.security.authorization.AuthorizationManager @@ -45,7 +45,7 @@ class StatelessSecurityFilterChainRegistrar( matcher: RequestMatcher, config: (HttpSecurity) -> Unit, ): SecurityFilterChainWrapper { - // 清除不必要的默认安全配置,优化无状态场景下的行为 + // 清除不必要默认安全配置,优化无状态场景下的行为 // 设置请求匹配器以确定过滤器链适用范围 // 配置 HTTP 请求的授权规则: // - 允许所有 OPTIONS 请求(通常用于跨域预检) diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/adapter/DynamicReactiveAuthorizationManagerAdapter.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/adapter/DynamicReactiveAuthorizationManagerAdapter.kt similarity index 87% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/adapter/DynamicReactiveAuthorizationManagerAdapter.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/adapter/DynamicReactiveAuthorizationManagerAdapter.kt index fd4f076..677079c 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/adapter/DynamicReactiveAuthorizationManagerAdapter.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/adapter/DynamicReactiveAuthorizationManagerAdapter.kt @@ -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.manager.DynamicReactiveAuthorizationManager -import com.gewuyou.forgeboot.security.authorize.api.resolver.PermissionResolver +import com.gewuyou.forgeboot.security.authorize.api.core.manager.AccessManager +import com.gewuyou.forgeboot.security.authorize.api.webflux.manager.DynamicReactiveAuthorizationManager +import com.gewuyou.forgeboot.security.authorize.api.core.resolver.PermissionResolver import org.springframework.security.authorization.AuthorizationDecision import org.springframework.security.core.Authentication import org.springframework.security.web.server.authorization.AuthorizationContext diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/customizer/ApiKeyServerHttpSecurityCustomizer.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/customizer/ApiKeyServerHttpSecurityCustomizer.kt new file mode 100644 index 0000000..7c953d2 --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/customizer/ApiKeyServerHttpSecurityCustomizer.kt @@ -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 + +/** + * API 密钥服务器 HTTP 安全定制器 + * + * 该类用于在 Spring WebFlux 环境下基于 API 密钥进行认证的安全配置定制。 + * 它实现了 ServerHttpSecurityCustomizer 接口,能将自定义的认证逻辑集成到安全链中。 + * + * @constructor + * @param apiKeyReactiveAuthenticationFilter 自定义的 WebFilter 实现,用于执行 API 密钥认证逻辑 + */ +class ApiKeyServerHttpSecurityCustomizer( + private val apiKeyReactiveAuthenticationFilter: WebFilter, +) : ServerHttpSecurityCustomizer { + /** + * 判断当前定制器是否支持处理指定的安全链配置 + * + * 此方法用于标识该定制器是否适用于特定的安全链配置。 + * 实现类应根据 chainId 参数决定是否启用此定制器的逻辑。 + * + * @param chainId 安全链的唯一标识符,用于区分不同的安全配置场景 + * @return Boolean 返回 true 表示支持该 chainId,否则不支持 + */ + override fun supports(chainId: String): Boolean { + return SecurityConstants.API_KEY_CHAIN_ID == chainId + } + + /** + * 自定义 ServerHttpSecurity 配置的方法 + * + * 此方法由框架调用,允许开发者插入自定义的安全配置逻辑。 + * 方法参数提供了 ServerHttpSecurity 实例,可用于链式配置。 + * + * @param http ServerHttpSecurity 实例,用于构建 WebFlux 安全配置 + */ + override fun customize(http: ServerHttpSecurity) { + // 将过滤器添加到安全链中的认证位置 + http.addFilterAt(apiKeyReactiveAuthenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION) + } +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/filter/ApiKeyReactiveAuthenticationFilter.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/filter/ApiKeyReactiveAuthenticationFilter.kt new file mode 100644 index 0000000..4bc2688 --- /dev/null +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/filter/ApiKeyReactiveAuthenticationFilter.kt @@ -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.ApiKeyAuthenticationToken +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 + +/** + * API 密钥反应式身份验证过滤器 + * + * 用于在 WebFlux 环境下通过 API 密钥进行身份验证的过滤器。 + * 它继承自 [AuthenticationWebFilter],并使用 [ApiKeyServerAuthenticationConverter] + * 将请求中的 API 密钥转换为认证对象 [ApiKeyAuthenticationToken]。 + * + * @property authenticationManager 身份验证管理器,用于处理身份验证请求 + * @since 2025-06-25 16:46:13 + * @author gewuyou + */ +class ApiKeyReactiveAuthenticationFilter( + authenticationManager: ReactiveAuthenticationManager +) : AuthenticationWebFilter(authenticationManager) { + + /** + * 初始化代码块,设置当前过滤器使用的身份验证转换器。 + * + * 此处将默认的转换逻辑替换为基于 API 密钥的身份验证转换器, + * 该转换器负责从请求头中提取并解析 API 密钥。 + */ + init { + setServerAuthenticationConverter(ApiKeyServerAuthenticationConverter()) + } + + /** + * 基于 API 密钥的身份验证转换器 + * + * 实现了 [ServerAuthenticationConverter] 接口,负责从 [ServerWebExchange] 中提取 API 密钥, + * 并将其转换为对应的认证对象 [ApiKeyAuthenticationToken]。 + */ + private class ApiKeyServerAuthenticationConverter : ServerAuthenticationConverter { + + /** + * 将传入的请求上下文转换为认证对象。 + * + * 此方法尝试从请求头中获取 `Authorization` 字段,并检查其是否以指定的前缀开头。 + * 如果匹配,则移除前缀并提取出 API 密钥,最终构造一个未认证的 [ApiKeyAuthenticationToken] 对象。 + * + * @param exchange 当前的服务器 Web 交换对象,包含请求信息 + * @return 返回一个 [Mono?] 类型的对象,如果成功提取 API 密钥则返回包含认证对象的 Mono; + * 否则返回空的 Mono。 + */ + 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(ApiKeyAuthenticationToken(apiKey, null)) + } else { + Mono.empty() + } + } + } +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/handler/ReactiveAuthorizationExceptionHandler.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/handler/ReactiveAuthorizationExceptionHandler.kt similarity index 93% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/handler/ReactiveAuthorizationExceptionHandler.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/handler/ReactiveAuthorizationExceptionHandler.kt index 01c0300..54668d6 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/handler/ReactiveAuthorizationExceptionHandler.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/handler/ReactiveAuthorizationExceptionHandler.kt @@ -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.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 org.springframework.http.HttpHeaders import org.springframework.http.HttpStatus diff --git a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/builder/StatelessSecurityWebFilterChainRegistrar.kt b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/registrar/StatelessSecurityWebFilterChainRegistrar.kt similarity index 96% rename from forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/builder/StatelessSecurityWebFilterChainRegistrar.kt rename to forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/registrar/StatelessSecurityWebFilterChainRegistrar.kt index 4823dfc..1032430 100644 --- a/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/builder/StatelessSecurityWebFilterChainRegistrar.kt +++ b/forgeboot-security/forgeboot-security-authorize/impl/src/main/kotlin/com/gewuyou/forgeboot/security/authorize/impl/webflux/registrar/StatelessSecurityWebFilterChainRegistrar.kt @@ -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.extension.cleanUnNeedConfig +import com.gewuyou.forgeboot.security.core.common.registrar.SecurityWebFilterChainRegistrar import com.gewuyou.forgeboot.security.core.common.wrapper.SecurityWebFilterChainWrapper import org.springframework.http.HttpMethod import org.springframework.security.authorization.ReactiveAuthorizationManager diff --git a/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/authorize/entities/ApiKeyPrincipal.kt b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/authorize/entities/ApiKeyPrincipal.kt new file mode 100644 index 0000000..b7cd58d --- /dev/null +++ b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/authorize/entities/ApiKeyPrincipal.kt @@ -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 ApiKeyPrincipal ( + val principal: String, + val authorities: List +) \ No newline at end of file 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 new file mode 100644 index 0000000..6e5760c --- /dev/null +++ b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/constants/SecurityConstants.kt @@ -0,0 +1,31 @@ +package com.gewuyou.forgeboot.security.core.common.constants + +/** + * 安全相关常量定义 + * + * 该对象存储与安全认证相关的通用常量,便于统一管理和维护。 + * + * @since 2025-06-25 16:02:05 + * @author gewuyou + */ +object SecurityConstants { + /** + * HTTP请求头中用于携带身份凭证的字段名称 + */ + const val AUTHORIZATION_HEADER = "Authorization" + + /** + * Bearer Token前缀,用于在请求头中标识Token类型 + */ + const val BEARER_PREFIX = "Bearer " + + /** + * API密钥请求头字段名称,用于在请求头中携带API认证标识 + */ + const val API_KEY_CHAIN_ID = "apiKey" + + /** + * 默认的API密钥标识 + */ + const val DEFAULT_CHAIN_ID = "default" +} \ No newline at end of file diff --git a/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/builder/SecurityFilterChainRegistrar.kt b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/registrar/SecurityFilterChainRegistrar.kt similarity index 96% rename from forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/builder/SecurityFilterChainRegistrar.kt rename to forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/registrar/SecurityFilterChainRegistrar.kt index 6325f2f..2c1d348 100644 --- a/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/builder/SecurityFilterChainRegistrar.kt +++ b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/registrar/SecurityFilterChainRegistrar.kt @@ -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 org.springframework.security.config.annotation.web.builders.HttpSecurity diff --git a/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/builder/SecurityWebFilterChainRegistrar.kt b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/registrar/SecurityWebFilterChainRegistrar.kt similarity index 95% rename from forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/builder/SecurityWebFilterChainRegistrar.kt rename to forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/registrar/SecurityWebFilterChainRegistrar.kt index 055eb4f..e9063a5 100644 --- a/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/builder/SecurityWebFilterChainRegistrar.kt +++ b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/registrar/SecurityWebFilterChainRegistrar.kt @@ -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 org.springframework.security.config.web.server.ServerHttpSecurity diff --git a/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/token/ApiKeyAuthenticationToken.kt b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/token/ApiKeyAuthenticationToken.kt new file mode 100644 index 0000000..649060d --- /dev/null +++ b/forgeboot-security/forgeboot-security-core/src/main/kotlin/com/gewuyou/forgeboot/security/core/common/token/ApiKeyAuthenticationToken.kt @@ -0,0 +1,23 @@ +package com.gewuyou.forgeboot.security.core.common.token + +import org.springframework.security.authentication.AbstractAuthenticationToken +import org.springframework.security.core.GrantedAuthority + +/** + *API 密钥认证令牌 + * + * @since 2025-06-25 13:06:54 + * @author gewuyou + */ +class ApiKeyAuthenticationToken( + val apiKey: String, + private val principal: Any?, + private val authorities: Collection = listOf() +) : AbstractAuthenticationToken(authorities) { + + override fun getCredentials(): Any = apiKey + + override fun getPrincipal(): Any? = principal + + override fun isAuthenticated(): Boolean = super.isAuthenticated +} \ No newline at end of file