Spring Boot - 不允许使用 POST 方法

Posted

技术标签:

【中文标题】Spring Boot - 不允许使用 POST 方法【英文标题】:Spring boot - POST method not allowed 【发布时间】:2018-03-14 18:30:00 【问题描述】:

我正在解决这个问题...我有一个带有 S2S 通信的 Spring Boot 应用程序。我有一个@RestController 方法,它应该接受 POST 请求。

这是控制器

@RestController
public class PaymentRestController 

@PostMapping("/util/paymentResponse")
    public void savePaymentResponse(@RequestParam boolean transaction_status, @RequestParam String usedToken,
            @RequestParam String transaction_message, @RequestParam String authCode,
            @RequestParam String transactionCode, @RequestParam String orderId, HttpServletRequest request) 
//business logic



如果我点击此链接,我会收到 405 错误,方法不允许

第一次我发现请求被 web 应用程序上启用的 CSFR 过滤器阻止了,所以我以这种方式配置了我的安全性

@Configuration
@ComponentScan("it.besmart")
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter

    @Autowired
    @Qualifier("customUserDetailsService")
    UserDetailsService userDetailsService;

    @Autowired
    CustomSuccessHandler customSuccessHandler;

    @Autowired
    CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    @Autowired
    DataSource dataSource;

    private final static Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);

    @Autowired
    public void configureGlobalService(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());

    

    @Bean
    public PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

    @Bean
    public SwitchUserFilter switchUserFilter() 
        SwitchUserFilter filter = new SwitchUserFilter();
        filter.setUserDetailsService(userDetailsService);
        filter.setSuccessHandler(customSuccessHandler);
        filter.setFailureHandler(customAuthenticationFailureHandler);
        return filter;
    

        protected void configure(HttpSecurity http) throws Exception 
            logger.debug("Webapp security configured");


            http

            .authorizeRequests()
                    .antMatchers("/",  "/home", "/contacts", "/faq", "/privacy", "/register", "/registrationConfirm", "/util/**", "/resendRegistrationToken","/park**", "/oauth/authorize", "/error")
                    .permitAll()
                    .antMatchers("/profile**", "/edit**","/payment**", "/plate**","/notification**", "/addPaymentMethod**", "/logout/impersonate**")
                    .access("hasRole('USER') or hasRole('NOPAYMENT')")
                    .antMatchers("/book**", "/manage**")
                    .access("hasRole('USER')")
                    .antMatchers("/admin**", "/login/impersonate**").access("hasRole('ADMIN')")
                    .antMatchers("/updatePassword").hasAuthority("CHANGE_PASSWORD_PRIVILEGE")

                    .and().formLogin().loginPage("/?login=login").loginProcessingUrl("/")                   .successHandler(customSuccessHandler).failureHandler(customAuthenticationFailureHandler).usernameParameter("email").passwordParameter("password").and().rememberMe().rememberMeParameter("remember-me").tokenRepository(persistentTokenRepository()).tokenValiditySeconds(86400).and().exceptionHandling().accessDeniedPage("/accessDenied")

                    .and().csrf().ignoringAntMatchers( "/util**")
                    .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/?logout=true").permitAll()


                    .and().addFilterAfter(switchUserFilter(), FilterSecurityInterceptor.class);

        

通过这种方式,我没有收到 CSRF 令牌异常,但仍然收到 405 错误。 这甚至不是 POST 的问题,因为如果我更改为 GET 请求和映射,我仍然会出现 405 错误......如果我尝试发送 POST,我在标题响应中看到 Allowed 方法是 POST,如果我在 GET 中发送它,我会看到允许的方法 POST... 很奇怪

我不知道在哪里看...

【问题讨论】:

只是为了排除与安全相关的问题,您可以尝试将属性 management.security.enabled=false 添加到您的 application.properties 并说明它是否可以这样工作? 什么都没有改变...问题仍然存在... 所以看起来不是安全问题...您如何发布您的请求?此外,尝试将 required=false 添加到所有 RequestParam,调试应用程序并在控制器的第一行放置断点。 像这样:@RequestParam(value = "yourParamName", required = false) 你是对的!有一个空参数!但奇怪的是我收到 405 错误... 【参考方案1】:

在我的情况下,端点有 ssl,即它是 https

在 Postman 中,我错误地使用了 http

http 对于 GETs 可以正常工作,但对于 POSTs 它返回不允许的 405 方法。如果您的端点期望它是,它必须是 https

如果您在 Spring 中打开了请求和响应日志记录,则上述情况下的 POST 端点将记录如下:

[2021-02-26T10:40:07+02:00] (my-app/fffffa343226e) 2021-02-26T08:40:07,915Z (UTC+0) [http-nio-80-exec-6] DEBUG o.s.w.f.CommonsRequestLoggingFilter - Before request [GET /api/v1/my-app, client=1.2.3.4, user=aUser]
[2021-02-26T10:40:07+02:00] (my-app/fffffa343226e) 2021-02-26T08:40:07,915Z (UTC+0) [http-nio-80-exec-6] WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported]
[2021-02-26T10:40:07+02:00] (my-app/fffffa343226e) 2021-02-26T08:40:07,916Z (UTC+0) [http-nio-80-exec-6] DEBUG o.s.w.f.CommonsRequestLoggingFilter - After request [GET /api/v1/my-app, client=1.2.3.4, user=aUser]

【讨论】:

【参考方案2】:

还记得检查协议。在我的情况下,它必须是 https 而不是 http

错误信息当然可以更具描述性!

【讨论】:

【参考方案3】:

在我的情况下,我通过以下方式在我的控制器中进行映射:

@RequestMapping(name = "/fetch", method = RequestMethod.POST)
public Long createFetch() throws IOException 
    return fetchService.doFetch();

如果您注意到,上面的映射是到name,但是请求可以使用这个。一旦我在@Controller 级别和方法级别应用相同的,我开始看到这个错误。将路径设置为value 解决了这个问题。

【讨论】:

【参考方案4】:

所以问题是其中一个参数为空。 在请求参数注释处添加 required=null 已解决,如下所示:

@RequestParam(value = "yourParamName", required = false)

这会导致 405,定义如下:

6.5.5.  405 Method Not Allowed

The 405 (Method Not Allowed) status code indicates that the method
received in the request-line is known by the origin server but not
supported by the target resource.  The origin server MUST generate an
Allow header field in a 405 response containing a list of the target
resource's currently supported methods.

A 405 response is cacheable by default; i.e., unless otherwise
indicated by the method definition or explicit cache controls (see
Section 4.2.2 of [RFC7234]).

当“目标资源”被定义时here:

【讨论】:

以上是关于Spring Boot - 不允许使用 POST 方法的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 返回 405 而不是 404 用于 POST 到未知 URL

使用spring boot将用户保存到h2时出错

(spring-boot) http 到 https 重定向,405 方法不允许消息

Spring Boot 多对多 post 方法不更新数据

Spring boot快速体验Web开发

Spring Boot 尝试访问 Post 请求 URL,但显示 GET 不支持