iam trying to upgrade my project from 2.1.1. to 3.1.1
i have some problem with concurrent session for example..
i am login with username \"AAA\" on browser
this will expire currently logged in user (same username and password). The new user can continue to login without any issue.
Create new implementation of SessionAuthenticationStrategy by adding this to src folder. In grails 3, (src/main/groovy) in grails (2.x src/groovy). I call this a custom name based on what you want to achieve save this as ConcurrentSingleSessionAuthenticationStrategy.groovy:
package com.myapp.test;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.util.Assert;
import org.springframework.security.core.session.SessionRegistry;
import grails.plugin.springsecurity.SpringSecurityUtils;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
/**
* Strategy used to register a user with the {@link SessionRegistry} after successful
* {@link Authentication}.
*
* <p>
* {@link RegisterSessionAuthenticationStrategy} is typically used in combination with
* {@link CompositeSessionAuthenticationStrategy} and
* {@link ConcurrentSessionControlAuthenticationStrategy}, but can be used on its own if
* tracking of sessions is desired but no need to control concurrency.
*
* <p>
* NOTE: When using a {@link SessionRegistry} it is important that all sessions (including
* timed out sessions) are removed. This is typically done by adding
* {@link HttpSessionEventPublisher}.
*
* @see CompositeSessionAuthenticationStrategy
*
* @author Luke Taylor
* @author Rob Winch
* @since 3.2
*/
public class ConcurrentSingleSessionAuthenticationStrategy implements
SessionAuthenticationStrategy {
private SessionRegistry sessionRegistry;
/**
* @param sessionRegistry the session registry which should be updated when the
* authenticated session is changed.
*/
public ConcurrentSingleSessionAuthenticationStrategy(SessionRegistry sessionRegistry) {
Assert.notNull(sessionRegistry, "SessionRegistry cannot be null");
this.sessionRegistry = sessionRegistry;
}
/**
* In addition to the steps from the superclass, the sessionRegistry will be removing
* with the new session information.
*/
public void onAuthentication(Authentication authentication,
HttpServletRequest request, HttpServletResponse response) {
def sessions = sessionRegistry.getAllSessions(
authentication.getPrincipal(), false);
def principals = sessionRegistry.getAllPrincipals()
sessions.each{
if(it.principal == authentication.getPrincipal()){
it.expireNow()
}
}
}
}
In resources.groovy:
import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy;
import org.springframework.security.core.session.SessionRegistryImpl;
import com.myapp.test.ConcurrentSingleSessionAuthenticationStrategy;
import org.springframework.security.web.session.ConcurrentSessionFilter
// Place your Spring DSL code here
beans = {
sessionRegistry(SessionRegistryImpl)
//I see you did not have this. Very dangerous!
sessionFixationProtectionStrategy(SessionFixationProtectionStrategy){
migrateSessionAttributes = true
alwaysCreateSession = true
}
//Initiate the bean
concurrentSingleSessionAuthenticationStrategy(ConcurrentSingleSessionAuthenticationStrategy,ref('sessionRegistry'))
registerSessionAuthenticationStrategy(RegisterSessionAuthenticationStrategy,ref('sessionRegistry'))
sessionAuthenticationStrategy(CompositeSessionAuthenticationStrategy,[ref('concurrentSingleSessionAuthenticationStrategy'),ref('sessionFixationProtectionStrategy'),ref('registerSessionAuthenticationStrategy')])
concurrentSessionFilter(ConcurrentSessionFilter,ref('sessionRegistry'))
}
In config, finally add this line:
grails.plugin.springsecurity.filterChain.filterNames = [ 'securityContextPersistenceFilter', 'logoutFilter', 'concurrentSessionFilter', 'rememberMeAuthenticationFilter', 'anonymousAuthenticationFilter', 'exceptionTranslationFilter', 'filterInvocationInterceptor' ]
Hope this helps.