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

Spring Boot JWT认证输入正确凭证仍报403错误排查

Spring Security登录返回403,成功认证方法未执行

在Postman中输入正确邮箱和密码登录,始终收到403错误。按预期,凭证正确时应完成认证,不会返回403。调试发现,即使凭证正确,successfulAuthentication方法从未执行,无法定位问题。


WebSecurity.java

package com.org.security;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;


import com.org.service.UserService;

@Configuration
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {

        private final UserService userDetailsService;
        private final BCryptPasswordEncoder bCryptPasswordEncoder;

        public WebSecurity(UserService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
            this.userDetailsService = userDetailsService;
            this.bCryptPasswordEncoder = bCryptPasswordEncoder;
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
            .cors().and()
            .csrf().disable();
            http.authorizeRequests()
            .antMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL)
            .permitAll()
            .anyRequest().authenticated().and().addFilter(getAuthenticationFilter());
            
            
            http.headers().frameOptions().disable();
        }
        
        protected AuthenticationFilter getAuthenticationFilter() throws Exception {
            final AuthenticationFilter filter = new AuthenticationFilter(authenticationManager());
            filter.setFilterProcessesUrl("/users/login");
            return filter;
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
        }

}

AuthenticationFilter.java

package com.org.security;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.org.SpringApplicationContext;
import com.org.service.UserService;
import com.org.shared.dto.UserDto;
import com.org.ui.model.request.UserLoginRequestModel;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;
    
    

    public AuthenticationFilter(AuthenticationManager authenticationManager) {
        
        this.authenticationManager=authenticationManager;
            
    }

    //this method will be trigerred when authenticating a user from his mail and password
    @Override
    public Authentication attemptAuthentication(HttpServletRequest req,
                                                HttpServletResponse res) throws AuthenticationException {
        try {
            //try block code will find the user and authenticate it
            
            //this will use the email and password in userLoginModel to authenticate
            //it will authenticate on the basis of email,password if found in the database a new function will be called
            UserLoginRequestModel creds = new ObjectMapper()
                    .readValue(req.getInputStream(), UserLoginRequestModel.class);
            
            return authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken( 
                            creds.getEmail(),
                            creds.getPassword(),
                            new ArrayList<>())
            );
            
          
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
       
    }
    //this runs on successfull authentication
    
     @Override
        protected void successfulAuthentication(HttpServletRequest req,
                                                HttpServletResponse res,
                                                FilterChain chain,
                                                Authentication auth) throws IOException, ServletException {
            
            String userName = ((User) auth.getPrincipal()).getUsername();
            
            String token = Jwts.builder()
                    .setSubject(userName)
                    .setExpiration(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME))
                    .signWith(SignatureAlgorithm.HS512, SecurityConstants.TOKEN_SECRET )
                    .compact();
            UserService userService = (UserService)SpringApplicationContext.getBean("userServiceImpl");
            UserDto userDto = userService.getUser(userName);
            
            res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
            res.addHeader("UserID", userDto.getUserId());

        }

    }
    

SecurityConstants.java

package com.org.security;

public class SecurityConstants {

    
    
    public static final long EXPIRATION_TIME = 864000000;
    public static final String TOKEN_PREFIX = "Bearer ";
    public static final String HEADER_STRING = "Authorization";
    public static final String SIGN_UP_URL = "/users";
    public static final String TOKEN_SECRET = "k";
}

Postman 403错误截图

Postman返回403错误


UserLoginRequestModel.java

package com.org.ui.model.request;

public class UserLoginRequestModel {

    private String email;
    private String password;

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:54:18