Spring Boot @PostMapping 端点未命中,而 @GetMapping 在添加 securityFilterChain 后有效

问题描述 投票:0回答:1

我正在使用 Spring Security 学习 Spring Boot,并且我的 AuthController 中的 @PostMapping 端点遇到问题。 @GetMapping 端点工作正常,但 @PostMapping 端点永远不会被命中。我已经使用 Postman 验证了该请求,一切似乎都是正确的。详情如下:

安全配置(SecurityConfig):

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
    @Bean
    public UserDetailsService userDetailsService() {
        // Define your custom UserDetailsService implementation
        return new CustomUserDetailsService();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(req ->
                        req.requestMatchers(
                                        "/auth/**",
                                        "/css/**.css",
                                        "/js/**"
                                ).permitAll()
                                .anyRequest().authenticated()
                )
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

        return http.build();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
}

AuthController:

@RestController
@RequestMapping("/auth")
public class AuthController {
    @GetMapping("/test")
    public String test() {
        return "Testing GET in Auth Ctrl.";
    }

    @PostMapping("/login")
    public String login(@RequestBody AuthRequest authRequest) {
        try {
            if(authRequest.getUsername() == null || authRequest.getPassword() == null)
                throw new AuthenticationException("AuthRequest is empty");

            // Assuming successful authentication, you would normally return a JWT token here
            return "Login successful!";
        } catch (AuthenticationException e) {
            return "Login failed!";
        }
    }
}

@Data
@NoArgsConstructor
class AuthRequest {
    private String username;
    private String password;
}

自定义用户详细信息服务:

@Service
public class CustomUserDetailsService implements UserDetailsService {
    private final Map<String, String> usersMap = new HashMap<>();

    @Autowired
    public CustomUserDetailsService() {
        // Initialize the usersMap with encoded passwords
        usersMap.put("ricky", "$2a$10$Dow1SE9N1XzFxXh3YDJIoO/b0Zi4DlCg8Up7X5DpIS9b/T/xkaHOO"); // password: 123
        usersMap.put("martin", "$2a$10$Dow1SE9N1XzFxXh3YDJIoO/b0Zi4DlCg8Up7X5DpIS9b/T/xkaHOO"); // password: 456
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if (usersMap.containsKey(username)) {
            return new User(username, usersMap.get(username), new ArrayList<>()); // Empty authorities list
        }

        // If this is thrown, then we won't generate a JWT token.
        throw new UsernameNotFoundException(username + " not found.");
    }
}

用邮递员测试:

网址:http://localhost:8080/auth/login 方法:邮寄 标头:内容类型:application/json 正文:原始 JSON 示例正文:

{
    "username": "ricky",
    "password": "123"
}

我尝试过的:

  1. 已验证@GetMapping端点是否有效。
  2. 确保 POST 请求格式正确并使用适当的标头发送。
  3. 检查安全配置中是否允许 /auth/login 端点。
  4. 添加了请求日志记录以查看 Spring 是否收到请求。
  5. 简化了控制器以排除其他潜在问题。

问题: 尽管执行了上述步骤,@PostMapping 端点永远不会被命中,并且不会记录任何错误消息。 @GetMapping 端点工作正常。

附加信息: pom.xml

任何关于为什么 @PostMapping 端点没有被命中的见解或建议将不胜感激!

java spring spring-boot spring-security
1个回答
0
投票

当然,如果 Spring Security Filter 返回禁止,它就不会到达你的方法:)

您还应该检查为什么会出现

403
,将日志记录级别设置为使用
logging.level.org.springframework.security=DEBUG
进行调试,以便您看到错误。

我愿意打赌,CSRF 正确地不允许您在没有 CSRF 令牌的情况下发送“危险”请求(基本上是任何其他请求,除了 GET)。

您应该首先发送某种请求(任何请求)以获得 CSRF cookie(自动添加到尚未拥有它的调用的响应中),然后将该 cookie 的值添加为 X-您的 POST 调用的 XSRF-TOKEN 标头。请参阅文档

如果您不依赖 cookie 进行身份验证并且不使用会话,您还可以考虑使用

关闭 CSRF
   http
       .csrf(AbstractHttpConfigurer::disable)
       // ...

© www.soinside.com 2019 - 2024. All rights reserved.