HTTP状态405 - 请求方法' POST'尝试提交spring security的自定义登录表单时不受支持

时间:2014-12-17 18:17:27

标签: spring

我正在使用弹簧,弹簧安全。我的应用程序有自定义登录页面jsp页面,我试图发布用户名,密码和csrf令牌,在后端我有一个控制器来捕获和验证登录详细信息。我正在使用tomcat。我使用spring security进行登录验证。当我从文件HTTP状态405提交登录时出现以下错误 - 请求方法' POST'不支持任何想法?

登录页面:

<div id="login-box">

    <h3>Login with Username and Password</h3>

    <c:if test="${not empty error}">
        <div class="error">${error}</div>
    </c:if>
    <c:if test="${not empty msg}">
        <div class="msg">${msg}</div>
    </c:if>

    <form name='loginForm' action="<c:url value='/login' />" method='POST'>

        <table>
            <tr>
                <td>User:</td>
                <td><input type='text' name='username' value=''></td>
            </tr>
            <tr>
                <td>Password:</td>
                <td><input type='password' name='password' /></td>
            </tr>
            <tr>
                <td colspan='2'><input name="submit" type="submit"
                    value="submit" /></td>
            </tr>
        </table>

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

    </form>
</div>

控制器类:

@Controller
public class HelloController {

@RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET)
public ModelAndView welcomePage() {

    ModelAndView model = new ModelAndView();
    model.addObject("title", "Spring Security Custom Login Form");
    model.addObject("message", "This is welcome page!");
    model.setViewName("hello");
    return model;

}

@RequestMapping(value = "/admin**", method = RequestMethod.GET)
public ModelAndView adminPage() {

    ModelAndView model = new ModelAndView();
    model.addObject("title", "Spring Security Custom Login Form");
    model.addObject("message", "This is protected page!");
    model.setViewName("admin");

    return model;

}

@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(@RequestParam(value = "error", required = false) String error,
        @RequestParam(value = "logout", required = false) String logout) {

    ModelAndView model = new ModelAndView();
    if (error != null) {
        model.addObject("error", "Invalid username and password!");
    }

    if (logout != null) {
        model.addObject("msg", "You've been logged out successfully.");
    }
    model.setViewName("login");

    return model;

}

Spring-Security Config:

<http auto-config="true">
  <intercept-url pattern="/admin**" access="ROLE_USER" />
  <form-login 
    login-page="/login" 
        default-target-url="/welcome" 
    authentication-failure-url="/login?error" 
    username-parameter="username"
    password-parameter="password" />
  <logout logout-success-url="/login?logout" />
  <!-- enable csrf protection -->
  <csrf/>
</http>

<authentication-manager>
  <authentication-provider>
    <user-service>
    <user name="mkyong" password="123456" authorities="ROLE_USER" />
    </user-service>
  </authentication-provider>
</authentication-manager>   

3 个答案:

答案 0 :(得分:2)

好的,我在这里看到的问题是在jsp表单中。表单操作不正确,Spring安全性尝试默认使用其他操作进行登录处理。即 / j_spring_security_check ,甚至你的邮件中的字段名称也不正确。

Username field : j_username
Password field : j_password

所以你需要做三件事才能让它发挥作用。

  1. 将jsp中的表单声明中的操作重命名为action =&#34;
  2. 将用户名字段重命名为j_username
  3. 将密码字段重命名为j_password
  4. Spring安全性确实提供了重命名所有内容的灵活性,但让我们先使用基本安全性。预计不会有其他变化

    修改

    我错过了阅读用户名和密码自定义。

    只做一件事(已添加login-processing-url属性):

    <http auto-config="true">
      <intercept-url pattern="/admin**" access="ROLE_USER" />
      <form-login 
         login-page="/login" 
         default-target-url="/welcome" 
         authentication-failure-url="/login?error" 
         login-processing-url="/login"
         username-parameter="username"
         password-parameter="password" />
      <logout logout-success-url="/login?logout" />
      <!-- enable csrf protection -->
      <csrf/>
    

答案 1 :(得分:0)

首先,您使用

重定向到登录页面
model.setViewName("login");

你使用弹簧安全吗?如果是,我不会在您的代码中看到与弹簧安全过滤器相关的任何内容。

我建议你看看那里

mykong example

或显然是 spring-reference

答案 2 :(得分:-2)

您的控制器只接受GET请求,您的表单使用POST。首先,我将尝试更改此配置。

@RequestMapping(value = "/login", method = RequestMethod.POST)

你也可以避免指定选项方法,这意味着GET和POST。