当向应用程序中不存在的端点发送 POST 请求时,服务器返回 405 而不是 404。对于具有现有端点的请求也会发生类似的问题,只要一切正常,状态代码就会返回 200,但是当发生内部服务器错误(例如找不到用户)时,http 响应变为 405(而不是 500)。使用 GET 请求,一切正常。
奇怪的是,如果我打开调试器,按照抛出错误的过程,它正在处理一个 500 错误。但显然最终某处出了问题,我得到了 405 返回。
我的网络安全配置:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private UserDetailsService jwtUserDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Value("${allowedOrigin}")
private String origin = "http://localhost:4200";
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
//You can enforce the use of HTTPS when your app is running on Heroku by adding
// the following configuration to your Spring Boot app.
httpSecurity.requiresChannel()
.requestMatchers(r - > r.getHeader("X-Forwarded-Proto") != null)
.requiresSecure();
httpSecurity
.cors()
.and().csrf()
.disable()
// dont authenticate this particular request
.authorizeRequests()
.antMatchers("/api/authenticate")
.permitAll()
// all other requests for /api need to be authenticated
.antMatchers("/api/**", "/admin/**")
.authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Add a filter to validate the tokens with every request
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
更新:
我没有任何 ControllerAdivce,也没有编写全局异常处理程序。
405 响应中的“Allow”标头显示为“GET, HEAD”,即使 POST 请求实际进入 POST 端点也是如此。
答案 0 :(得分:0)
根据您的 HttpSecurity 配置,您只允许 Post 请求,对于其他 HTTP 方法(如 GET、PUT....),您将获得 405(不允许的方法)。
antMatchers(HttpMethod.POST).permitAll();
答案 1 :(得分:0)
事实证明,一个带有未实现的“/error”路径方法的 ErrorController 导致了问题。每当抛出异常或错误时,它都会解析为“/error”并被 ErrorController 接收,出于某种原因将其解析为 405。实现该方法后,HTTP 状态将正确返回。
@RestController
public class RoutingController implements ErrorController {
private static final String PATH = "/error";
@RequestMapping(value = PATH)
public String handleError(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
return String.format("<html><body><h2>Error Page</h2><div>Status code: <b>%s</b></div>" +
"<div>Exception Message: <b>%s</b></div><body></html>",
statusCode, exception == null ? "N/A" : exception.getMessage());
}
public String getErrorPath() {
return PATH;
}
}