简体   繁体   English

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

[英]Spring Security - 405 Request Method 'POST' Not Supported

I have implemented Spring Security to my project, but I am getting status 405 when I try to log in. I have already added csrf token in the form .我已经在我的项目中实现了 Spring Security,但是当我尝试登录时得到状态 405。我已经在form中添加了csrf令牌。

This is the error I am getting when I send username and password: HTTP Status 405 - Request method 'POST' not supported这是我在发送用户名和密码时遇到的错误: HTTP Status 405 - Request method 'POST' not supported

Spring version: 4.0.2.RELEASED春季版:4.0.2.RELEASED

<div class="login-form">
    <c:url var="loginUrl" value="/login" />
    <form action="${loginUrl}" method="post" class="form-horizontal">
        <c:if test="${param.error != null}">
            <div class="alert alert-danger">
                <p>Invalid username and password.</p>
            </div>
        </c:if>
        <c:if test="${param.logout != null}">
            <div class="alert alert-success">
                <p>You have been logged out successfully.</p>
            </div>
        </c:if>
        <div class="input-group input-sm">
            <label class="input-group-addon" for="username">
                <i class="fa fa-user"></i>
            </label>
            <input type="text" class="form-control" id="username"
                name="clientusername" placeholder="Enter Username" required>
        </div>
        <div class="input-group input-sm">
            <label class="input-group-addon" for="password">
                <i class="fa fa-lock"></i>
            </label>
            <input type="password" class="form-control" id="password"
                name="clientpassword" placeholder="Enter Password" required>
        </div>

        <input type="hidden" name="${_csrf.parameterName}"
            value="${_csrf.token}" />

        <div class="form-actions">
            <input type="submit" class="btn btn-block btn-primary btn-default"
                value="Log in">
        </div>
    </form>
</div>

Security Configuration:安全配置:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

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

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests()
        .antMatchers("/", "/home").permitAll()
        .antMatchers("/admin/**").access("hasRole('ADMIN')")
        .and().formLogin().loginPage("/login")
        .usernameParameter("clientusername").passwordParameter("clientpassword")
        .and().csrf()
        .and().exceptionHandling().accessDeniedPage("/Access_Denied");
//        .and().csrf().disable();
    }

Controller:控制器:

@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView loginPage() {
    return new ModelAndView("login");
}

@RequestMapping(value="/logout", method = RequestMethod.GET)
public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth != null){    
        new SecurityContextLogoutHandler().logout(request, response, auth);
    }
    return "redirect:/login?logout";
}

 @RequestMapping(value = "/Access_Denied", method = RequestMethod.GET)
    public ModelAndView accessDeniedPage(ModelMap model) {
        model.addAttribute("user", getPrincipal());
        return new ModelAndView("accessDenied");
    }

 @RequestMapping(value = "/admin", method = RequestMethod.GET)
    public ModelAndView adminPage(ModelMap model) {
        model.addAttribute("user", getPrincipal());
        return new ModelAndView("admin");
    }

 private String getPrincipal(){
        String userName = null;
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        if (principal instanceof UserDetails) {
            userName = ((UserDetails)principal).getUsername();
        } else {
            userName = principal.toString();
        }
        return userName;
    }

Almost every topic about this issue says that we need to add csrf token, but I already added.几乎每个关于这个问题的话题都说我们需要添加csrf令牌,但我已经添加了。 Am I missing something?我错过了什么吗?

First of all csrf is enabled by default in Spring as of Spring 4.0 so there no need to explicitly enable it yourself.首先,从 Spring 4.0 开始,Spring 中默认启用csrf ,因此无需自己显式启用它。

Secondly, there is no endpoint for you to authenticate your login.其次,您没有端点可以验证您的登录信息。 What you're doing is sending a request to /login which only takes a GET request.你正在做的是向/login发送一个请求,它只接受一个GET请求。 You could create another controller method to receive that POST request and authenticate or you could use a UserDetailsService .您可以创建另一个控制器方法来接收该POST请求并进行身份验证,或者您可以使用UserDetailsService

SecurityConfiguration安全配置

protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .antMatchers("/login-form")
                        .anonymous()
                    .and()
                .formLogin()
                    .loginPage("/user-login") 
                    .defaultSuccessUrl("/admin", true) // the second parameter is for enforcing this url always
                    .loginProcessingUrl("/login")
                    .failureUrl("/user-login")
                    .permitAll();
}

@Autowired 
private UserDetailsService userDetailsService;  

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    BCryptPasswordEncoder pe = new  BCryptPasswordEncoder();
    auth.userDetailsService(userDetailsService).passwordEncoder(pe);
}

Here our view page is /user-login and the processing url is /login this means in your controller you need remove the mapping for /login and add the following:这里我们的视图页面是/user-login ,处理 url 是/login这意味着在你的控制器中你需要删除/login的映射并添加以下内容:

Controller控制器

@RequestMapping(value="/user-login", method=RequestMethod.GET)
public ModelAndView loginForm() {
    return new ModelAndView("login-form");
}

And change your view.并改变你的看法。

View (login-form.jsp)查看(登录表单.jsp)

<c:url value="/login" var="loginUrl"/>
<form action="${loginUrl}" method="post" modelAttribute="user">
    Username: <input type="text" id="username" name="username" placeholder=""><br>
    Password: <input type="password" id="password" name="password" placeholder=""><br>

    <input type="hidden"
    name="${_csrf.parameterName}"
    value="${_csrf.token}"/>
    <button type="submit">Login</button>
</form>

I started getting the same thing when I added a successForwardUrl and found that the response on sucessful login is a POST to that endpoint or to "/" if not set.当我添加一个successForwardUrl并发现成功登录时的响应是对该端点的 POST 或“/”(如果未设置)时,我开始得到同样的结果。 Once I enabled POST on the defined endpoint as well as GET all was fine.一旦我在定义的端点上启用 POST 以及 GET 一切都很好。

Check your web.xml file you might forgot to keep "securityFilterChain"检查您可能忘记保留“securityFilterChain”的 web.xml 文件

Use this code in web.xml file在 web.xml 文件中使用此代码

<!-- Security configuration goes here -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

You are calling for a POST yet have only defined GET methods.您正在调用 POST 但只定义了 GET 方法。 Change your endpoint to RequestMethod.POST将您的端点更改为 RequestMethod.POST

You can set two endpoints for one url.您可以为一个 url 设置两个端点。 But you cannot set any request parameter as required.但是您不能根据需要设置任何请求参数。 As I saw your request map for login, you can set your request method like this:当我看到您的登录请求映射时,您可以像这样设置请求方法:

@RequestMapping(value = "/login", method = { RequestMethod.GET, RequestMethod.POST })
public ModelAndView loginPage() {
    return new ModelAndView("login");
}

If you are using JSP/JSTL如果您使用的是 JSP/JSTL

Change改变

<form action="${loginUrl}" method="post"></form> 

to

<form:form action="${loginUrl}" method="post" </form:form>

with tag declaration带标签声明

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

solve my problem解决我的问题

Ensure that the Spring Security filter chain is registered.确保 Spring Security 过滤器链已注册。

With Java configuration, this can be done by creating a class that extends AbstractSecurityWebApplicationInitializer .使用 Java 配置,这可以通过创建一个扩展AbstractSecurityWebApplicationInitializer的类来完成。

public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {
}

Alternatively, edit web.xml and add the following code.或者,编辑 web.xml 并添加以下代码。 (See the documentation .) (请参阅文档。)

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 405 - 不支持请求方法“POST” Spring MVC + Spring 安全 - 405 - Request method 'POST' not supported Spring MVC + Spring Security 错误 405:不支持请求方法“POST” - Spring Security Java Config - Error 405: Request method 'POST' not supported - Spring Security Java Config HTTP状态405 - 使用Spring Security的Spring MVC中不支持请求方法'POST' - HTTP Status 405 - Request method 'POST' not supported in Spring MVC with Spring Security 具有Spring Security的Spring-mvc获得HTTP状态405-请求方法&#39;POST&#39;不支持 - Spring-mvc with spring security getting HTTP Status 405 - Request method 'POST' not supported HTTP状态405-请求方法&#39;POST&#39;不支持Spring Security Java Config - HTTP Status 405 - Request method 'POST' not supported Spring Security Java Config 启用弹簧安全性的POST请求显示“不支持405 GET” - POST request says “405 GET not supported” with Spring security enabled Spring MVC的CURL POST请求给出405方法&#39;POST&#39;不支持 - Curl POST request for spring mvc gives 405 Method 'POST' not supported 405不允许的方法:请求方法&#39;POST&#39;不支持| Ajax / Spring MVC - 405 Method Not Allowed : Request method 'POST' not supported | Ajax/Spring MVC Spring Boot安全请求方法&#39;POST&#39;不受支持 - Spring Boot Security Request method 'POST' not supported 不支持请求方法“POST” Spring 安全 - Request method 'POST' not supported Spring Security
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM