Spring security authentication: get username witho

2019-03-18 19:41发布

问题:

I'm new at spring framework. I'm creating a login page for my webapp and I want the user to login before any action on the app. If the user enters good credentials everything it's ok and working, but if enters bad ones I want to display a message and keep the username on the input element. Displaying a message is not a problem, but I'm not able to keep the username in my jps file without using the deprecated variable SPRING_SECURITY_LAST_USERNAME.

Hope someone can help me, I'm using Spring 3.

UPDATE: the requirements says I don't want to display the username on the url.

回答1:

The documentation of the deprecated constant tells exactly what you should do:

/**
 * @deprecated If you want to retain the username, cache it in a customized {@code AuthenticationFailureHandler}
 */
@Deprecated
public static final String SPRING_SECURITY_LAST_USERNAME_KEY =
           "SPRING_SECURITY_LAST_USERNAME";

Something like this:

public class UserNameCachingAuthenticationFailureHandler
    extends SimpleUrlAuthenticationFailureHandler {

    public static final String LAST_USERNAME_KEY = "LAST_USERNAME";

    @Autowired
    private UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter;

    @Override
    public void onAuthenticationFailure(
            HttpServletRequest request, HttpServletResponse response,
            AuthenticationException exception)
            throws IOException, ServletException {

        super.onAuthenticationFailure(request, response, exception);

        String usernameParameter =
            usernamePasswordAuthenticationFilter.getUsernameParameter();
        String lastUserName = request.getParameter(usernameParameter);

        HttpSession session = request.getSession(false);
        if (session != null || isAllowSessionCreation()) {
            request.getSession().setAttribute(LAST_USERNAME_KEY, lastUserName);
        }
    }
}

In your security config:

<security:http ...>
    ...
    <security:form-login
        authentication-failure-handler-ref="userNameCachingAuthenticationFailureHandler"
    ...
    />
</security:http>

<bean 
    id="userNameCachingAuthenticationFailureHandler"
    class="so.UserNameCachingAuthenticationFailureHandler">
    <property name="defaultFailureUrl" value="/url/to/login?error=true"/>
</bean>

In your login.jsp:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="true" %>

...

<%--in the login form definition--%>
<input id="j_username" name="j_username" type="text" 
    value="<c:out value="${sessionScope.LAST_USERNAME}"/>"/>


回答2:

If anyone comes here who is having this problem in Grails Spring security. You can now use the following-

import grails.plugin.springsecurity.SpringSecurityUtils;

Now use SpringSecurityUtils.SPRING_SECURITY_LAST_USERNAME_KEY this will work and is not deprecated.