Spring security authentication: get username without SPRING_SECURITY_LAST_USERNAME
Solution 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}"/>"/>
Solution 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.
droidpl
Updated on June 05, 2022Comments
-
droidpl about 2 years
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.
-
zagyi over 11 yearsNo problem. Note that there is space for improvement at some points. E.g. hard-coding the session attribute's name in the .jsp is not elegant. Ideally it should refer to the constant defined in
UserNameCachingAuthenticationFailureHandler
. (I have to admint I don't know how to achieve this indirection.) -
droidpl over 11 yearsI didn't know this could be achieved! But for now that's all I need, this not security properly but a little trick to make the user life better! It's incredible that I coudn't find another simple solution like this anywhere! ;)
-
Jason almost 11 yearsis it just me, or is that a crap load of code just to keep the username input on the form?
-
AxeEffect almost 10 years
request.getParameter("j_username")
can also be called successfully from theRedirectStrategy.sendRedirect()
method if you're implementing it as a customised bean (actually this bean is a member variable/field of theAuthenticationFailureHandler
class/bean). -
Jonathas Pacífico over 7 yearsusernamePasswordAuthenticationFilter is null. Spring Security 4. How can I solve this?
-
Bassam over 7 yearsI have added the line @Autowired UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter; but I am getting the error no qualifying bean UsernamePasswordAuthenticationFilter I am using Spring security 4.2.0 and MVC.
-
Bassam over 7 yearsHow can this possibly work? The filter chain creates the usernamePasswordAuthenticationFilter. But to create the filter chain, we need the handler. But the handler depends on the filter which has not been created yet. I don't this works in Spring 4
-
Amir over 2 yearshow to create bean of UsernamePasswordAuthenticationFilter and specified AuthenticationManager?