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

Spring Boot集成JWT时请求/authenticate返回403错误求助

排查Spring Boot JWT集成中/authenticate接口返回403的问题

以下是几个关键排查方向和解决方法:

1. 检查JwtRequestFilter是否跳过了/authenticate请求

你的SecurityConfig中把JwtRequestFilter放在了UsernamePasswordAuthenticationFilter之前,如果这个过滤器没有对/authenticate路径做放行处理,会尝试从请求中解析JWT令牌,但该接口本身就是获取令牌的入口,请求中没有JWT,过滤器可能直接返回403。

修改JwtRequestFilter的doFilterInternal方法,增加路径判断:

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
        throws ServletException, IOException {

    // 跳过认证接口,直接放行
    if (request.getRequestURI().equals("/authenticate")) {
        chain.doFilter(request, response);
        return;
    }

    // 其余JWT验证逻辑...
    final String authorizationHeader = request.getHeader("Authorization");
    String username = null;
    String jwt = null;

    if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
        jwt = authorizationHeader.substring(7);
        username = jwtUtil.extractUsername(jwt);
    }

    if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
        UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
        if (jwtUtil.validateToken(jwt, userDetails)) {
            UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                    userDetails, null, userDetails.getAuthorities());
            authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authToken);
        }
    }
    chain.doFilter(request, response);
}

2. 确认存在正确处理/authenticate的控制器

你没有提供控制器代码,必须确保有对应的@RestController映射/authenticate路径,并且处理POST请求:

@RestController
public class AuthController {

    private final AuthenticationManager authenticationManager;
    private final JwtUtil jwtUtil;
    private final UserDetailsService userDetailsService;

    // 构造注入依赖
    public AuthController(AuthenticationManager authenticationManager, JwtUtil jwtUtil, UserDetailsService userDetailsService) {
        this.authenticationManager = authenticationManager;
        this.jwtUtil = jwtUtil;
        this.userDetailsService = userDetailsService;
    }

    @PostMapping("/authenticate")
    public ResponseEntity<?> authenticate(@RequestBody AuthRequest authRequest) throws Exception {
        // 验证用户名密码
        try {
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
            );
        } catch (BadCredentialsException e) {
            throw new Exception("用户名或密码错误", e);
        }

        // 生成JWT返回
        UserDetails userDetails = userDetailsService.loadUserByUsername(authRequest.getUsername());
        String jwtToken = jwtUtil.generateToken(userDetails);
        return ResponseEntity.ok(new AuthResponse(jwtToken));
    }
}

(注:AuthResponse是简单的DTO类,包含String token字段和对应的getter/setter)

3. 检查UserDetailsService实现与密码加密

确保你的UserDetailsService实现正确加载用户信息,且存储的密码是通过BCryptPasswordEncoder加密后的字符串。比如如果你的用户密码是"pass",存储时应该是:

passwordEncoder.encode("pass")

如果存储的是明文密码,AuthenticationManager会验证失败,但此时通常返回401而非403,不过也可能因配置差异导致异常。

4. 确认SecurityConfig的请求方法匹配

如果你的/authenticate只接受POST请求,可以在antMatchers中明确指定方法,避免其他方法请求被拦截:

.antMatchers(HttpMethod.POST, "/authenticate").permitAll()

(需要导入org.springframework.http.HttpMethod)

内容的提问来源于stack exchange,提问作者Iván Jesús Monferrer Marzá

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 16:19:59