405 - 请求方法“POST”不支持 Spring MVC + Spring Security

Posted

技术标签:

【中文标题】405 - 请求方法“POST”不支持 Spring MVC + Spring Security【英文标题】:405 - Request method 'POST' not supported Spring MVC + Spring Security 【发布时间】:2020-08-12 02:14:30 【问题描述】:

抱歉重复我已经看到了很多关于这个主题的问题,但没有人能帮助我。 当我在登录表单中输入正确的登录数据时,一切正常。当我在登录表单中输入不正确的登录数据时,重定向到“loginProcessingUrl()”是“/sign-in-handler”,但我在控制器中没有用于 /sign-in-handler 映射的 POST-endpoint,因为该端点必须由春季安全。但我有405。 这是我的代码:

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private DataSource dataSource;

    @Bean
    public PersistentTokenRepository persistentTokenRepository() 
        JdbcTokenRepositoryImpl persistentTokenRepository = new JdbcTokenRepositoryImpl();
        persistentTokenRepository.setDataSource(dataSource);
        return persistentTokenRepository;
    

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

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder());
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/my-profile", "/edit", "/edit/**", "/remove").hasAnyAuthority(Constants.USER)
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginPage("/sign-in")
                .loginProcessingUrl("/sign-in-handler")
                .usernameParameter("uid")
                .passwordParameter("password")
                .defaultSuccessUrl("/my-profile")
                .failureForwardUrl("/sign-in-failed")
                .and()
                .logout()
                .logoutUrl("/sign-out")
                .logoutSuccessUrl("/welcome")
                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")
                .and()
                .rememberMe()
                .rememberMeParameter("remember-me")
                .key("resume-online-key")
                .tokenRepository(persistentTokenRepository());
    

sign-in.jsp

        <form action='<spring:url value="/sign-in-handler"/>' method="post">
            <c:if test="$sessionScope.SPRING_SECURITY_LAST_EXCEPTION != null">
                <div class="alert alert-danger" role="alert">
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                        $sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message 
                    <c:remove var="SPRING_SECURITY_LAST_EXCEPTION" scope="session" />
                </div>
            </c:if>
            <div class="help-block">Вы можете использовать Ваши UID или Email или Phone в качестве логина</div>
            <div class="form-group">
                <label for="uid">Логин</label> <input id="uid" name="uid" class="form-control" placeholder="UID или Email или Phone" required autofocus>
            </div>
            <div class="form-group">
                <label for="password">Пароль</label> <input id="password" type="password" name="password" class="form-control" placeholder="Password" required>
            </div>
            <div class="form-group">
                <label><input type="checkbox" name="remember-me" value="true"> Запомнить меня</label>
            </div>
                <button type="submit" class="btn btn-success">Войти</button>
   </form>

ViewLoginController.java

@Controller
public class ViewLoginController 

    @GetMapping("sign-in")
    public String signIn() 
        return "sign-in";
    

    @GetMapping("/sign-in-failed")
    public String signInFailed(HttpSession httpSession)
        if(httpSession.getAttribute("SPRING_SECURITY_LAST_EXCEPTION") == null)
            return "redirect:/sign-in";
        
        return "sign-in";
    

但我有 - https://prnt.sc/s79zwz 我试过:在jsp spring:url、c:url、$pageContext.request.contextPath上更改url,只是'/'、daoAuthenticationProvider ... 感谢您的帮助

【问题讨论】:

【参考方案1】:

我认为你可以使用failureUrl,而不是failureForwardUrl,例如:

and()
      .formLogin()
      .loginPage("/login")
      .loginProcessingUrl("/login/authenticate")
      .failureUrl("/login?param.error=bad_credentials")

两者之间的区别在于failureForwardUrl可能执行服务器端转发(例如,您观察到端点的 POST),而failureUrl 使用平台的默认重定向策略和将导致浏览器重定向(HTTP 302)。文档真的很模糊,至少对我来说造成了很多混乱。

【讨论】:

您的解决方案是解决这个烦人的 405 案例的关键。但是很好奇,什么时候必须使用failureForwardUrl

以上是关于405 - 请求方法“POST”不支持 Spring MVC + Spring Security的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC HTTP 状态 405 - 不支持请求方法“POST”

Spring:状态 405。不支持请求方法“POST”

HTTP 状态 405 - 不支持请求方法“POST”(Spring MVC)

org.springframework.web.servlet.PageNotFound - 请求方法'POST'不支持http状态405

SpringMVC HTTP 状态 405 - 不支持请求方法“POST”

WebApi Post 方法总是返回“请求的资源不支持 http 方法 'GET'。”状态:405 方法不允许