You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security 6中Token过期时AuthenticationEntryPoint配置不生效问题

问题解决:自定义AuthenticationEntryPoint未触发及中文错误提示配置

问题原因

当使用Spring Security的oauth2ResourceServer(jwt())时,框架会为OAuth2相关的认证异常(如JWT过期、签名无效)默认使用BearerTokenAuthenticationEntryPoint,而非你配置的全局userAuthenticationEntryPoint,导致自定义逻辑未执行,同时返回默认英文错误头。

解决方案

1. 修改SecurityFilterChain配置

在oauth2ResourceServer块中显式指定自定义的AuthenticationEntryPoint,确保OAuth2认证异常走自定义逻辑:

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
    jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(new KeycloakRoleConverter(request));
    return http
            .cors().and()
            .exceptionHandling()
            .authenticationEntryPoint(userAuthenticationEntryPoint)
            .and()
            .addFilterAfter(new UserIdentityContextFilter(contextHolder), BearerTokenAuthenticationFilter.class)
            .authorizeHttpRequests(
                    authorize -> authorize
                            .requestMatchers("/v1/corporate/{corporateId}/process-executor/**").access(corporateAuthManager)
                            .requestMatchers("/v1/**").authenticated()
                            .anyRequest().denyAll()
            )
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and().csrf().disable()
            .oauth2ResourceServer(oauth2 ->
                    oauth2.jwt().jwtAuthenticationConverter(jwtAuthenticationConverter)
                            .and()
                            // 为OAuth2资源服务器指定自定义EntryPoint
                            .authenticationEntryPoint(userAuthenticationEntryPoint)
            )
            .build();
}

2. 优化自定义AuthenticationEntryPoint,返回中文提示

根据异常类型匹配对应的中文错误信息,覆盖默认英文提示:

import com.ba.cms.admin.dtos.ExceptionBean;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.jwt.JwtException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.OutputStream;

@Component
public class UserAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) throws IOException, ServletException {
        ExceptionBean bean;
        // 根据JWT异常类型返回对应中文提示
        if (authException instanceof JwtException) {
            String errorMsg = authException.getMessage();
            if (errorMsg.contains("expired")) {
                bean = new ExceptionBean(401, "未授权:令牌已过期");
            } else if (errorMsg.contains("invalid signature")) {
                bean = new ExceptionBean(401, "未授权:令牌签名无效");
            } else {
                bean = new ExceptionBean(401, "未授权:无效的令牌");
            }
        } else {
            bean = new ExceptionBean(401, "未授权:请提供有效的认证信息");
        }
        
        // 明确设置响应为JSON格式
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        
        OutputStream outputStream = response.getOutputStream();
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(outputStream, bean);
        outputStream.flush();
    }

}

内容的提问来源于stack exchange,提问作者Assaduzzaman Assad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 12:55:07