简体   繁体   中英

Spring Security - can't login after entering invalid password

I just setup Spring Security and it's working great. I can log in and out using my custom form. I have logged-in then out multiple times successively with no problem. Oddly, if I try to login with the wrong password, I can no longer log in again - it takes me to the "loginFailed" page every time I try to login after that. Does anyone know how to fix this?

Here is my 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>

My login form:

<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>

My login controller:

@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";
    }
}

If you're returning to the same page you logged into, the model is carried through. Since you're adding an attribute to that model, you're presumably checking to see if that attribute is set on the view page. Once it gets set, nothing will unset it until your session objects are cleared.

To confirm, change this:

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

And then check your console.

Well, I don't know what the problem was, but I was able to resolve it. I just found an older SO post: Spring security blocks user after failed login . Timh's answer of switching to Spring 3.0.7.RELEASE (from 3.0.6) worked for me. Sorry for double-posting.

If anyone know why this was happening in 3.0.6, I'd be interested to know.

This is because: https://jira.springsource.org/browse/SEC-1493

org.springframework.security.core.userdetails.eraseCredentials() is being invoked on authentication.

Solution should be parameter erase-credentials="false" for authentication-manager, but apparently it doesn't worked for me in Spring 3.1.0 or 3.1.3.

Work-around would be to re-load users' details on each authentication request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM