mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-14 14:19:08 +08:00
feat: 删除PigxBootSecurityServerConfiguration文件并优化授权服务器配置(jdk17-dev)
删除`PigxBootSecurityServerConfiguration`文件,将相关配置迁移至`AuthorizationServerConfiguration`。 优化`AuthorizationServerConfiguration`中的授权服务器安全策略,移除不必要的条件注解`@ConditionalOnProperty`。 修复`FormIdentityLoginConfigurer`中的表单登录处理URL,确保与授权服务器配置一致。
This commit is contained in:
1 parent
a00f4f81a4
commit
cfae5e1c05
3 files changed
+34
-197
No files matched your search
+18
-23
@@ -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.FormAuthenticationFailureHandler;
|
||||||
import com.pig4cloud.pigx.common.security.handler.SsoLogoutSuccessHandler;
|
import com.pig4cloud.pigx.common.security.handler.SsoLogoutSuccessHandler;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.Ordered;
|
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.DelegatingAuthenticationConverter;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -79,38 +77,35 @@ public class AuthorizationServerConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||||
@ConditionalOnProperty(value = "security.micro", matchIfMissing = true)
|
|
||||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http,
|
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http,
|
||||||
PigxAuthenticationSuccessEventHandler successEventHandler,
|
PigxAuthenticationSuccessEventHandler successEventHandler,
|
||||||
PigxAuthenticationFailureEventHandler failureEventHandler) throws Exception {
|
PigxAuthenticationFailureEventHandler failureEventHandler) throws Exception {
|
||||||
|
// 配置授权服务器的安全策略,只有/oauth2/**的请求才会走如下的配置
|
||||||
|
http.securityMatcher("/oauth2/**");
|
||||||
|
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
|
||||||
|
|
||||||
// 增加验证码过滤器
|
// 增加验证码过滤器
|
||||||
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
|
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
// 增加密码解密过滤器
|
// 增加密码解密过滤器
|
||||||
http.addFilterBefore(passwordDecoderFilter, UsernamePasswordAuthenticationFilter.class);
|
http.addFilterBefore(passwordDecoderFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|
||||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
|
|
||||||
http.with(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点
|
http.with(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点
|
||||||
tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter()) // 注入自定义的授权认证Converter
|
tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter()) // 注入自定义的授权认证Converter
|
||||||
.accessTokenResponseHandler(successEventHandler) // 登录成功处理器
|
.accessTokenResponseHandler(successEventHandler) // 登录成功处理器
|
||||||
.errorResponseHandler(failureEventHandler);// 登录失败处理器
|
.errorResponseHandler(failureEventHandler);// 登录失败处理器
|
||||||
}).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证
|
}).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证
|
||||||
oAuth2ClientAuthenticationConfigurer.errorResponseHandler(failureEventHandler))// 处理客户端认证异常
|
oAuth2ClientAuthenticationConfigurer.errorResponseHandler(failureEventHandler))// 处理客户端认证异常
|
||||||
.authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint// 授权码端点个性化confirm页面
|
.authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint// 授权码端点个性化confirm页面
|
||||||
.consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)), Customizer.withDefaults());
|
.consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)), Customizer.withDefaults())
|
||||||
|
.authorizeHttpRequests(authorizeRequests -> authorizeRequests.anyRequest().authenticated());
|
||||||
|
|
||||||
AntPathRequestMatcher[] requestMatchers = new AntPathRequestMatcher[]{
|
// 设置 Token 存储的策略
|
||||||
AntPathRequestMatcher.antMatcher("/token/**"), AntPathRequestMatcher.antMatcher("/actuator/**"),
|
http.with(authorizationServerConfigurer.authorizationService(authorizationService)// redis存储token的实现
|
||||||
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的实现
|
|
||||||
.authorizationServerSettings(
|
.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());
|
http.with(new FormIdentityLoginConfigurer(), Customizer.withDefaults());
|
||||||
DefaultSecurityFilterChain securityFilterChain = http.build();
|
DefaultSecurityFilterChain securityFilterChain = http.build();
|
||||||
|
|
||||||
|
|||||||
+16
-18
@@ -9,28 +9,26 @@ import org.springframework.security.config.annotation.web.configurers.AbstractHt
|
|||||||
/**
|
/**
|
||||||
* @author lengleng
|
* @author lengleng
|
||||||
* @data 2022-06-04
|
* @data 2022-06-04
|
||||||
*
|
* <p>
|
||||||
* 基于授权码模式 统一认证登录 spring security & sas 都可以使用 所以抽取成 HttpConfigurer
|
* 基于授权码模式 统一认证登录 spring security & sas 都可以使用 所以抽取成 HttpConfigurer
|
||||||
*/
|
*/
|
||||||
public final class FormIdentityLoginConfigurer
|
public final class FormIdentityLoginConfigurer
|
||||||
extends AbstractHttpConfigurer<FormIdentityLoginConfigurer, HttpSecurity> {
|
extends AbstractHttpConfigurer<FormIdentityLoginConfigurer, HttpSecurity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(HttpSecurity http) throws Exception {
|
public void init(HttpSecurity http) throws Exception {
|
||||||
http.formLogin(formLogin -> {
|
http.formLogin(formLogin -> {
|
||||||
formLogin.loginPage("/token/login");
|
formLogin.loginPage("/token/login");
|
||||||
formLogin.loginProcessingUrl("/token/form");
|
formLogin.loginProcessingUrl("/oauth2/form");
|
||||||
formLogin.failureHandler(new FormAuthenticationFailureHandler());
|
formLogin.failureHandler(new FormAuthenticationFailureHandler());
|
||||||
formLogin.successHandler(new TenantSavedRequestAwareAuthenticationSuccessHandler());
|
formLogin.successHandler(new TenantSavedRequestAwareAuthenticationSuccessHandler());
|
||||||
|
})
|
||||||
|
.logout(logout -> logout.logoutUrl("/oauth2/logout")
|
||||||
|
.logoutSuccessHandler(new SsoLogoutSuccessHandler())
|
||||||
|
.deleteCookies("JSESSIONID")
|
||||||
|
.invalidateHttpSession(true)) // SSO登出成功处理
|
||||||
|
|
||||||
})
|
.csrf(AbstractHttpConfigurer::disable);
|
||||||
.logout() // SSO登出成功处理
|
}
|
||||||
.logoutSuccessHandler(new SsoLogoutSuccessHandler())
|
|
||||||
.deleteCookies("JSESSIONID")
|
|
||||||
.invalidateHttpSession(true)
|
|
||||||
.and()
|
|
||||||
.csrf()
|
|
||||||
.disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
-156
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注入授权模式实现提供方
|
|
||||||
* <p>
|
|
||||||
* 1. 密码模式 </br>
|
|
||||||
* 2. 短信登录 </br>
|
|
||||||
*/
|
|
||||||
@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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user