1

我刚刚设置了 Spring Security,它工作得很好。我可以使用我的自定义表单登录和注销。我已经连续多次登录然后退出,没有问题。奇怪的是,如果我尝试使用错误的密码登录,我将无法再次登录 - 此后每次尝试登录时都会进入“loginFailed”页面。有谁知道如何解决这一问题?

这是我的security-config.xml:

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">


<http use-expressions="true">
    <intercept-url pattern="/secureA.htm" access="isAuthenticated()" /> 
    <intercept-url pattern="/secureB.htm" access="isAuthenticated()" /> 
    <form-login login-page="/login.htm" default-target-url="/secureA.htm" 
        authentication-failure-url="/loginFailed.htm"/>
    <logout logout-success-url="/login" />
</http>

<authentication-manager>
  <authentication-provider>
    <password-encoder hash="sha">
    </password-encoder>
    <user-service>
      <user name="user" password="pass" 
            authorities="ROLE_USER, ROLE_ADMIN" />
    </user-service>
  </authentication-provider>
</authentication-manager>

</beans:beans>

我的登录表格:

<form action="<c:url value='j_spring_security_check' />" method="post">
Username:&nbsp;<input type="text" name="j_username" /><br/>
    Password:&nbsp;<input type="password" name="j_password" /><br/>
    <input type="submit" value="Login" /><br/>
</form>

我的登录控制器:

@Controller
public class LoginController {

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String welcome(ModelMap m) {
        return "login";
    }

    @RequestMapping(value = "/loginFailed", method = RequestMethod.GET)
    public String failed(ModelMap m) {
        m.addAttribute("error", "Invalid username or password");
        return "login";
    }

    @RequestMapping("logout.htm")
    public String logout(ModelMap m) {
        return "redirect:login.htm";
    }
}
4

3 回答 3

0

如果您返回到您登录的同一页面,则该模型将被执行。由于您正在向该模型添加一个属性,因此您可能正在检查该属性是否已在视图页面上设置。一旦它被设置,在你的会话对象被清除之前什么都不会取消它。

要确认,请更改:

@RequestMapping(value = "/login", method = RequestMethod.GET)
public String welcome(ModelMap m) {
  System.out.println(m.getAttribute("error");
  return "login";
}

然后检查您的控制台。

于 2012-04-10T23:12:14.533 回答
0

好吧,我不知道问题是什么,但我能够解决它。我刚刚发现了一个较旧的 SO 帖子:Spring security blocks user after failed login。Timh 切换到 Spring 3.0.7.RELEASE(从 3.0.6 开始)的答案对我有用。抱歉重复发布。

如果有人知道为什么会在 3.0.6 中发生这种情况,我很想知道。

于 2012-04-10T23:56:23.087 回答
0

这是因为: https ://jira.springsource.org/browse/SEC-1493

org.springframework.security.core.userdetails.eraseCredentials() 在身份验证时被调用。

解决方案应该是 authentication-manager 的参数 erase-credentials="false",但显然它在 Spring 3.1.0 或 3.1.3 中对我不起作用。

解决方法是在每个身份验证请求上重新加载用户的详细信息。

于 2013-01-17T13:40:11.903 回答