springboot~3.x版本的认证逻辑,你可以将except
分享于 点击 21419 次 点评:209
springboot~3.x版本的认证逻辑,你可以将except
在 Spring Boot 3.4.x 中,HttpSecurity
的 and()
方法已经被标记为过时,因此我们需要采用新的 Lambda 风格 API 来配置安全性。你可以将 exceptionHandling()
移到 HttpSecurity
的顶层配置中,而不是在 authorizeHttpRequests
的内部。
authenticationEntryPoint和accessDeniedHandler的自定义
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import java.io.IOException;
public class CustomAccessDeineHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getWriter().write("{\"error\": \"forbidden\", \"message\": \"" + accessDeniedException.getMessage() + "\"}");
}
}
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import java.io.IOException;
/**
* 默认的认证入口点,当用户未通过认证时会触发此类,返回401状态码和错误信息。
* @author lind
* @date 2025/5/28 16:59
* @since 1.0.0
*/
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("{\"error\": \"Unauthorized\", \"message\": \"" + authException.getMessage() + "\"}");
}
}
HandlerConfig注册bean
@Configuration
public class HandlerConfig {
@Bean
@ConditionalOnMissingBean
AuthenticationEntryPoint authenticationEntryPoint() {
return new CustomAuthenticationEntryPoint();
}
@Bean
@ConditionalOnMissingBean
public AccessDeniedHandler accessDeniedHandler() {
return new CustomAccessDeineHandler();
}
}
WebSecurityConfig代码
@EnableWebSecurity
public class WebSecurityConfig {
private UaaProperty uaaProperty;
private AuthenticationEntryPoint authenticationEntryPoint;
private AccessDeniedHandler accessDeniedHandler;
public WebSecurityConfig(UaaProperty uaaProperty, AuthenticationEntryPoint authenticationEntryPoint, AccessDeniedHandler accessDeniedHandler) {
this.uaaProperty = uaaProperty;
this.authenticationEntryPoint = authenticationEntryPoint;
this.accessDeniedHandler = accessDeniedHandler;
}
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter(uaaProperty);
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
Set<String> set = new HashSet<>();
if (uaaProperty.getPermitUrl() != null && uaaProperty.getPermitUrl().length > 0) {
Collections.addAll(set, uaaProperty.getPermitUrl());
}
http.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(set.toArray(new String[]{})).permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(exceptionHandling ->
exceptionHandling
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler)
)
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
JwtAuthenticationFilter实现自定义验证逻辑
public class JwtAuthenticationFilter extends OncePerRequestFilter {
// 配置白名单策略,不走当前doFilterInternal
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
}
}
新版3.x的SPI风格自动装配
- resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.xxx.uaa.keycloak.config.UaaProperty
com.xxx.uaa.keycloak.config.WebSecurityConfig
com.xxx.uaa.keycloak.config.HandlerConfig
关键点解释
-
Lambda 风格 API:使用
exceptionHandling(exceptionHandling -> ...)
的方式来设置authenticationEntryPoint
和accessDeniedHandler
,这符合新的配置风格,避免了使用过时的方法。 -
结构清晰:通过这种方法,你的代码结构更加清晰,逻辑分离也更明显。
-
保持原有逻辑:其余部分的逻辑保持不变,仍然可以根据需要添加其他的配置。
注意事项
- 确保你的 Spring Security 版本已经更新到 5.4 或更高版本,以支持这种新的配置方式。
- 如果你有其他的异常处理或安全配置,也可以在同一链中继续添加。
作者:仓储大叔,张占岭,
荣誉:微软MVP
QQ:853066980
支付宝扫一扫,为大叔打赏!
用户点评