I want to detect when a user enter in my web page with Login form or remember-me cookie, and i want to execute code for register login, but this dont work. I dont know if exists other method for get my goal.
I test it this solutions:
- http://learn.eastros.com/2012/07/11/springsecurity-capturing-rememberme-success-event/ . Here, its necessary define all class manually, filters, services and handler for login, logout and remember-me.
- Recording logins with Spring Security. This post try a easier solution, only defines a same handler for success Login and success remember-me. But dont work.
- For other hand, here remember-me and authentication-success-handler say that the handler for form-login and remember-me cant be same class, and i will should implements AuthenticationSuccessHandler for remmeber-me handler. Didnt work too.
- I tried define filter before and after position of REMEMBER_ME_FILTER too. Nothing.
QUESTIONS
- Is possible use a filter REMEMBER-ME using form-login?
- security:http configuration needs indicate auto-config="false" and implement filters for login, logout and remember me as first link?
- Is it Necessary that I implement my Service, and provider or I can implement filter only?
My configuration:
security-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
ref="customAuthenticationProvider">
</security:authentication-provider>
</security:authentication-manager>
<bean id="customAuthenticationProvider" class="com.treebuk.config.CustomAuthenticationProvider"></bean>
<bean id="customUserDetailsService" class="com.treebuk.config.CustomUserDetailsService"></bean>
<bean id="customAuthenticationSuccessHandler" class="com.treebuk.config.CustomAuthenticationSuccessHandler"></bean>
<bean id="customRememberMeAuthenticationSuccessHandler" class="com.treebuk.config.CustomRememberMeAuthenticationSuccessHandler"></bean>
<bean id="customLogoutSuccessHandler" class="com.treebuk.config.CustomLogoutSuccessHandler"></bean>
<bean id="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"></bean>
<bean id="customRememberMeService" class="com.treebuk.config.CustomRememberMeService">
<constructor-arg value="MYKEY" />
<constructor-arg ref="customUserDetailsService"/>
</bean>
<bean id="customRememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<!-- key needs to be same as that provided to customRememberMeService. -->
<constructor-arg value="MYKEY"/>
</bean>
<bean id="rememberMeFilter" class="com.treebuk.config.CustomRememberMeAuthenticationFilter">
<constructor-arg ref="authenticationManager"/>
<constructor-arg ref="customRememberMeService"/>
</bean>
<security:http >
<security:intercept-url pattern="/" access="permitAll" />
<security:intercept-url pattern="/login/**" access="permitAll" />
<security:intercept-url pattern="/logout" access="permitAll" />
<security:intercept-url pattern="/**" access="denyAll" />
<security:form-login
authentication-success-handler-ref="customAuthenticationSuccessHandler"
authentication-failure-url="/login?error=true"
login-page="/login"
password-parameter="lgPassword"
username-parameter="lgUsername" />
<security:logout
success-handler-ref="customLogoutSuccessHandler"
logout-url="/logout"
invalidate-session="true" />
<security:csrf disabled="true" />
<security:remember-me
user-service-ref="customUserDetailsService"
remember-me-parameter="lgRememberMe"
token-validity-seconds="100" />
<security:custom-filter ref="rememberMeFilter" after="REMEMBER_ME_FILTER" />
<security:session-management>
<security:concurrency-control max-sessions="1" />
</security:session-management>
</security:http>
</beans>
login.jsp
<c:url var="loginUrl" value="/login" />
<form action="${loginUrl}" method="post">
<input type="hidden" name="spring-security-redirect" value="<c:out value="${param.r}" />">
<label for="txt_username">Usuario:</label>
<input type="text" id="txt_username" name="lgUsername" />
<br />
<label for="txt_password">Contraseña:</label>
<input type="password" id="txt_password" name="lgPassword">
<br />
<label for="chck_remeberme">Recordarme:</label>
<input type="checkbox" id="chck_remeberme" name="lgRememberMe" checked="checked" />
<br />
<input name="submit" type="submit" value="Identificarse" />
</form>
CustomRememberMeAuthenticationFilter.java
public class CustomRememberMeAuthenticationFilter extends RememberMeAuthenticationFilter {
public CustomRememberMeAuthenticationFilter(AuthenticationManager authenticationManager, RememberMeServices rememberMeServices) {
super(authenticationManager, rememberMeServices);
// TODO Auto-generated constructor stub
}
@Override
protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) {
// TODO: User has been auto-logged using a remember me cookie, do your stuff here
String x = "OK";
x += "";
String y = x;
}
}
CustomRememberMeService.java ( I comment body extractRememberMeCookie because else request.getHeader("remember-me") == null and throw a null exception)
public class CustomRememberMeService extends TokenBasedRememberMeServices{
public static final int TOKEN_VALIDITY_SECONDS = 15; // 60*30=30 minutes
public CustomRememberMeService(String key, UserDetailsService userDetailsService) {
super(key, userDetailsService);
}
@Override
protected String extractRememberMeCookie(HttpServletRequest request) {
// String rememberMe = request.getHeader("remember-me");
// int startIndex = "remember-me=".length();
// int endIndex = rememberMe.indexOf("; ", startIndex);
// return rememberMe.substring(startIndex, endIndex);
return "";
}
@Override
protected int calculateLoginLifetime(HttpServletRequest request, Authentication authentication) {
return TOKEN_VALIDITY_SECONDS;
}
}
CustomAuthenticationProvider.java, (**here is where i decrypt and compare the user password)
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider{
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public Authentication authenticate(Authentication authLoginForm) throws AuthenticationException {
String principal = authLoginForm.getName();
String credenctials = (String) authLoginForm.getCredentials();
User user = (User) customUserDetailsService.loadUserByUsername(principal);
if (user != null) {
if (passwordEncoder.matches(credenctials, user.getPassword())) {
System.out.println("Usuario identificado correctamente");
return new UsernamePasswordAuthenticationToken(principal.toLowerCase(), user.getPassword(), user.getAuthorities());
}
else
{
System.out.println("Contraseña incorrecta");
throw new BadCredentialsException("Error de autentificación");
}
}
else
{
throw new BadCredentialsException("Error de autentificación");
}
}
@Override
public boolean supports(Class<?> arg0) {
return true;
}
}
CustomAuthenticationSuccessHandler.java
@Component
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
@Autowired
private UserService userService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
User user = userService.findByAlias(authentication.getName().toLowerCase());
**// CODE FOR REGISTER LOGIN USER**
setDefaultTargetUrl("URL");
super.onAuthenticationSuccess(request, response, authentication);
}
}
CustomLogoutSuccessHandler.java
@Component
public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
if (authentication != null) {
// do something
}
setDefaultTargetUrl("/login");
super.onLogoutSuccess(request, response, authentication);
}
}
CustomRememberMeAuthenticationSuccessHandler,java (this code used when tried a solution where use a hablder for success form-login and other for success remember-me --> remember-me and authentication-success-handler)
@Service
public class CustomRememberMeAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Autowired
private UserService userService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
User user = userService.findByAlias(authentication.getName().toLowerCase());
**// CODE FOR REGISTER LOGIN USER BY REMEMBER-ME**
}
}