diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfiguration.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfiguration.java
index 232cfd298..7ecb8f149 100644
--- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfiguration.java
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfiguration.java
@@ -33,7 +33,6 @@ import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.security.handler.FormAuthenticationFailureHandler;
import com.pig4cloud.pigx.common.security.handler.SsoLogoutSuccessHandler;
import lombok.RequiredArgsConstructor;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@@ -57,7 +56,6 @@ import org.springframework.security.web.authentication.AuthenticationFailureHand
import org.springframework.security.web.authentication.DelegatingAuthenticationConverter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import java.util.Arrays;
@@ -79,38 +77,35 @@ public class AuthorizationServerConfiguration {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
- @ConditionalOnProperty(value = "security.micro", matchIfMissing = true)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http,
PigxAuthenticationSuccessEventHandler successEventHandler,
PigxAuthenticationFailureEventHandler failureEventHandler) throws Exception {
+ // 配置授权服务器的安全策略,只有/oauth2/**的请求才会走如下的配置
+ http.securityMatcher("/oauth2/**");
+ OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
+
// 增加验证码过滤器
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
// 增加密码解密过滤器
http.addFilterBefore(passwordDecoderFilter, UsernamePasswordAuthenticationFilter.class);
- OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
http.with(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点
- tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter()) // 注入自定义的授权认证Converter
- .accessTokenResponseHandler(successEventHandler) // 登录成功处理器
- .errorResponseHandler(failureEventHandler);// 登录失败处理器
- }).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证
- oAuth2ClientAuthenticationConfigurer.errorResponseHandler(failureEventHandler))// 处理客户端认证异常
- .authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint// 授权码端点个性化confirm页面
- .consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)), Customizer.withDefaults());
+ tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter()) // 注入自定义的授权认证Converter
+ .accessTokenResponseHandler(successEventHandler) // 登录成功处理器
+ .errorResponseHandler(failureEventHandler);// 登录失败处理器
+ }).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证
+ oAuth2ClientAuthenticationConfigurer.errorResponseHandler(failureEventHandler))// 处理客户端认证异常
+ .authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint// 授权码端点个性化confirm页面
+ .consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)), Customizer.withDefaults())
+ .authorizeHttpRequests(authorizeRequests -> authorizeRequests.anyRequest().authenticated());
- AntPathRequestMatcher[] requestMatchers = new AntPathRequestMatcher[]{
- AntPathRequestMatcher.antMatcher("/token/**"), AntPathRequestMatcher.antMatcher("/actuator/**"),
- AntPathRequestMatcher.antMatcher("/code/**"), AntPathRequestMatcher.antMatcher("/css/**"),
- AntPathRequestMatcher.antMatcher("/error")};
-
- http.authorizeHttpRequests(authorizeRequests -> {
- // 自定义接口、端点暴露
- authorizeRequests.requestMatchers(requestMatchers).permitAll();
- authorizeRequests.anyRequest().authenticated();
- })
- .with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现
+ // 设置 Token 存储的策略
+ http.with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现
.authorizationServerSettings(
- AuthorizationServerSettings.builder().issuer(SecurityConstants.PIGX_LICENSE).build()), Customizer.withDefaults());
+ AuthorizationServerSettings.builder().issuer(SecurityConstants.PIGX_LICENSE).build()),
+ Customizer.withDefaults());
+
+ // 设置授权码模式登录页面
http.with(new FormIdentityLoginConfigurer(), Customizer.withDefaults());
DefaultSecurityFilterChain securityFilterChain = http.build();
diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/core/FormIdentityLoginConfigurer.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/core/FormIdentityLoginConfigurer.java
index 0d790965b..d0d3c92cd 100644
--- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/core/FormIdentityLoginConfigurer.java
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/support/core/FormIdentityLoginConfigurer.java
@@ -9,28 +9,26 @@ import org.springframework.security.config.annotation.web.configurers.AbstractHt
/**
* @author lengleng
* @data 2022-06-04
- *
+ *
* 基于授权码模式 统一认证登录 spring security & sas 都可以使用 所以抽取成 HttpConfigurer
*/
public final class FormIdentityLoginConfigurer
- extends AbstractHttpConfigurer {
+ extends AbstractHttpConfigurer {
- @Override
- public void init(HttpSecurity http) throws Exception {
- http.formLogin(formLogin -> {
- formLogin.loginPage("/token/login");
- formLogin.loginProcessingUrl("/token/form");
- formLogin.failureHandler(new FormAuthenticationFailureHandler());
- formLogin.successHandler(new TenantSavedRequestAwareAuthenticationSuccessHandler());
+ @Override
+ public void init(HttpSecurity http) throws Exception {
+ http.formLogin(formLogin -> {
+ formLogin.loginPage("/token/login");
+ formLogin.loginProcessingUrl("/oauth2/form");
+ formLogin.failureHandler(new FormAuthenticationFailureHandler());
+ formLogin.successHandler(new TenantSavedRequestAwareAuthenticationSuccessHandler());
+ })
+ .logout(logout -> logout.logoutUrl("/oauth2/logout")
+ .logoutSuccessHandler(new SsoLogoutSuccessHandler())
+ .deleteCookies("JSESSIONID")
+ .invalidateHttpSession(true)) // SSO登出成功处理
- })
- .logout() // SSO登出成功处理
- .logoutSuccessHandler(new SsoLogoutSuccessHandler())
- .deleteCookies("JSESSIONID")
- .invalidateHttpSession(true)
- .and()
- .csrf()
- .disable();
- }
+ .csrf(AbstractHttpConfigurer::disable);
+ }
}
diff --git a/pigx-boot/src/main/java/com/pig4cloud/pigx/bootstrap/PigxBootSecurityServerConfiguration.java b/pigx-boot/src/main/java/com/pig4cloud/pigx/bootstrap/PigxBootSecurityServerConfiguration.java
deleted file mode 100644
index a492354f3..000000000
--- a/pigx-boot/src/main/java/com/pig4cloud/pigx/bootstrap/PigxBootSecurityServerConfiguration.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- *
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- *
- */
-
-package com.pig4cloud.pigx.bootstrap;
-
-import com.pig4cloud.pigx.auth.support.core.PigxDaoAuthenticationProvider;
-import com.pig4cloud.pigx.auth.support.filter.PasswordDecoderFilter;
-import com.pig4cloud.pigx.auth.support.filter.ValidateCodeFilter;
-import com.pig4cloud.pigx.auth.support.handler.PigxAuthenticationFailureEventHandler;
-import com.pig4cloud.pigx.auth.support.handler.PigxAuthenticationSuccessEventHandler;
-import com.pig4cloud.pigx.auth.support.password.OAuth2ResourceOwnerPasswordAuthenticationProvider;
-import com.pig4cloud.pigx.auth.support.sms.OAuth2ResourceOwnerSmsAuthenticationProvider;
-import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
-import com.pig4cloud.pigx.common.security.component.PermitAllUrlProperties;
-import com.pig4cloud.pigx.common.security.component.ResourceAuthExceptionEntryPoint;
-import lombok.RequiredArgsConstructor;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.Ordered;
-import org.springframework.core.annotation.Order;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.Customizer;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
-import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
-import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
-import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
-import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
-import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
-import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
-import org.springframework.security.web.DefaultSecurityFilterChain;
-import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.authentication.AuthenticationConverter;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
-
-/**
- * @author lengleng 认证授权服务器配置
- */
-@Configuration
-@RequiredArgsConstructor
-public class PigxBootSecurityServerConfiguration {
-
- private final ResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint;
-
- private final OpaqueTokenIntrospector customOpaqueTokenIntrospector;
-
- private final AuthenticationConverter accessTokenRequestConverter;
-
- private final OAuth2AuthorizationService authorizationService;
-
- private final PasswordDecoderFilter passwordDecoderFilter;
-
- private final OAuth2TokenGenerator oAuth2TokenGenerator;
-
- private final ValidateCodeFilter validateCodeFilter;
-
- private final PermitAllUrlProperties permitAllUrl;
-
- @Bean
- @Order(Ordered.HIGHEST_PRECEDENCE)
- public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http,
- PigxAuthenticationSuccessEventHandler successEventHandler,
- PigxAuthenticationFailureEventHandler failureEventHandler) throws Exception {
- OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
-
- // 增加验证码过滤器
- http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
- // 增加密码解密过滤器
- http.addFilterBefore(passwordDecoderFilter, UsernamePasswordAuthenticationFilter.class);
-
- // 认证服务器配置
- http.with(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点
- tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter) // 注入自定义的授权认证Converter
- .accessTokenResponseHandler(successEventHandler) // 登录成功处理器
- .errorResponseHandler(failureEventHandler);// 登录失败处理器
- }).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证
- oAuth2ClientAuthenticationConfigurer.errorResponseHandler(failureEventHandler))// 处理客户端认证异常
- , Customizer.withDefaults())
- .with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现
- .authorizationServerSettings(
- AuthorizationServerSettings.builder().issuer(SecurityConstants.PIGX_LICENSE).build()),
- Customizer.withDefaults());
-
- // 资源服务器配置
- AntPathRequestMatcher[] requestMatchers = permitAllUrl.getIgnoreUrls()
- .stream()
- .map(AntPathRequestMatcher::new)
- .toList()
- .toArray(new AntPathRequestMatcher[]{});
-
- http.authorizeHttpRequests(authorizeRequests -> authorizeRequests.requestMatchers(requestMatchers)
- .permitAll()
- .anyRequest()
- .authenticated())
- .oauth2ResourceServer(
- oauth2 -> oauth2.opaqueToken(token -> token.introspector(customOpaqueTokenIntrospector))
- .authenticationEntryPoint(resourceAuthExceptionEntryPoint))
- .exceptionHandling(configurer -> configurer.authenticationEntryPoint(resourceAuthExceptionEntryPoint))
- .headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
- .csrf(AbstractHttpConfigurer::disable);
-
- http.with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现
- .authorizationServerSettings(
- AuthorizationServerSettings.builder().issuer(SecurityConstants.PIGX_LICENSE).build()),
- Customizer.withDefaults());
-
- DefaultSecurityFilterChain securityFilterChain = http.build();
-
- // 注入自定义授权模式实现
- addCustomOAuth2GrantAuthenticationProvider(http);
- return securityFilterChain;
- }
-
- /**
- * 注入授权模式实现提供方
- *
- * 1. 密码模式
- * 2. 短信登录
- */
- @SuppressWarnings("unchecked")
- private void addCustomOAuth2GrantAuthenticationProvider(HttpSecurity http) {
- AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
- OAuth2AuthorizationService authorizationService = http.getSharedObject(OAuth2AuthorizationService.class);
-
- OAuth2ResourceOwnerPasswordAuthenticationProvider resourceOwnerPasswordAuthenticationProvider = new OAuth2ResourceOwnerPasswordAuthenticationProvider(
- authenticationManager, authorizationService, oAuth2TokenGenerator);
-
- OAuth2ResourceOwnerSmsAuthenticationProvider resourceOwnerSmsAuthenticationProvider = new OAuth2ResourceOwnerSmsAuthenticationProvider(
- authenticationManager, authorizationService, oAuth2TokenGenerator);
-
- // 处理 UsernamePasswordAuthenticationToken
- http.authenticationProvider(new PigxDaoAuthenticationProvider());
- // 处理 OAuth2ResourceOwnerPasswordAuthenticationToken
- http.authenticationProvider(resourceOwnerPasswordAuthenticationProvider);
- // 处理 OAuth2ResourceOwnerSmsAuthenticationToken
- http.authenticationProvider(resourceOwnerSmsAuthenticationProvider);
- }
-
-}