Spring Boot 401 POST 请求未经授权

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

我有一个配置了安全性的应用程序,它使用基本身份验证(登录名+密码)。 我的主要问题是当我在 Postman 中发出

POST
请求时,我收到
401 Unauthorized
。但是,当我执行相同的请求但将其更改为
GET
请求时,它返回状态为
200
的数据。这是我的安全配置和附加屏幕截图。

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends VaadinWebSecurity {

    private static final String LOGIN_URL = "/login";
    private static final String LOGIN_PROCESSING_URL = "/login";
    private static final String LOGIN_FAILURE_URL = "/login?error";
    private static final String LOGOUT_SUCCESS_URL = "/";
    private static final String DENIED_PAGE_URL = "/404";

    private final UserService userService;
    private final PasswordEncoder passwordEncoder;

    public SecurityConfiguration(UserService userService, PasswordEncoder passwordEncoder) {
        this.userService = userService;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeHttpRequests(auth -> {
                    auth.requestMatchers("/login", "/register").permitAll();
                    auth.requestMatchers("/public/**").permitAll();
                    auth.requestMatchers("/icons/**").permitAll();
                    auth.requestMatchers("/images/**").permitAll();
                    auth.requestMatchers("/api/**").authenticated();
                    auth.requestMatchers("/private/**").authenticated();
                    auth.requestMatchers("/admin/**").hasAnyRole("ADMIN", "SUPER_ADMIN");
                })
                .formLogin(loginForm -> {
                    loginForm.loginPage(LOGIN_URL);
                    loginForm.loginProcessingUrl(LOGIN_PROCESSING_URL);
                    loginForm.failureUrl(LOGIN_FAILURE_URL);
                })
                .logout(logout -> logout.logoutSuccessUrl(LOGOUT_SUCCESS_URL))
                .exceptionHandling(e -> {
                    e.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
                    e.accessDeniedPage(DENIED_PAGE_URL);
                })
                .httpBasic();

        super.configure(http);
        setLoginView(http, LoginView.class);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
        daoAuthenticationProvider.setUserDetailsService(userService);
        return daoAuthenticationProvider;
    }

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

}

这是我的要求

@PostMapping("/save")
public Expense saveExpense(@RequestBody ExpenseRequest expenseRequest) {
    Expense expense = expenseConvertor.convertToExpense(expenseRequest);
    return expenseService.saveExpense(expense);
}

获取请求

其他信息

  • 标头中提供身份验证的任何其他
    GET
    请求都可以正常工作
  • PUT
    POST
    DELETE
    请求,全部抛出
    401 Unauthorized

任何帮助都会很棒,谢谢

spring-boot spring-security postman http-status-code-401
3个回答
1
投票

我猜您正在处理 CSRF 错误,了解发生情况的最快方法是将

logging.level.org.springframework.security=TRACE
添加到您的
application.properties
并分析您的日志。

您已在

SecurityConfiguration#configure(HttpSecurity)
方法的第二行中禁用了 CSRF 保护,但是,在下面的几行中,您正在调用
super.configure(http);
,这又会再次配置 CSRF 保护。尝试删除该行或提供 CSRF 令牌。


0
投票

由于 csrf,通常只会发生 GET 传递,因为您禁用了它。我认为您应该保存安全配置文件并重新启动您的应用程序。


0
投票

代替 http.csrf().disable() 你应该使用 http.csrf(csrf -> csrf.ignoringRequestMatchers( "/url1/","/url2/")) 来让 csrf 知道你想忽略特定的 API 调用, 我们不使用 disable() 这是由 Spring Security 本身提供的,以保护应用程序免受使用浏览器 cookie 发生的不必要的威胁

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