Recently tuned the Spring security cluster session sharing, using the custom sessionregistry, but found how also do not work, turned over Stackoverfllow, also did not find a reliable way, and finally their own debug, Found the problem.
This article is based on spring3.1.5,spring security 2.0.4
The initial configuration is as follows:
<beans:bean id= "Sessionregistry" class= "Com.shop.core.security.support.SessionRegistryImpl" scope= "Singleton" > <beans:property name= "CacheManager" ref= "CacheManager"/></beans:bean><bean:http auto-config= " False "entry-point-ref=" Loginurlentrypoint ">...<bean:concurrent-session-control max-sessions=" 200000 " Exception-if-maximum-exceeded= "false" Expired-url= "/outline.htm" session-registry-alias= "SessionRegistry"/> ...</bean:http>
Debug found that the custom Sessionregistryimpl class is also loaded, but the final system call is still the original
Org.springframework.security.concurrent.SessionRegistryImpl
The reason is found by reading the source code, which is explained in comments:
public class concurrentsessionsbeandefinitionparser implements beandefinitionparser { static final String ATT_EXPIRY_URL = "Expired-url"; static final String ATT_MAX_SESSIONS = "Max-sessions"; static final String ATT_EXCEPTION_IF_MAX_EXCEEDED = " Exception-if-maximum-exceeded "; static final string att_session_registry _alias = "Session-registry-alias"; static final string att_ session_registry_ref = "Session-registry-ref"; public Beandefinition parse (Element element, parsercontext parsercontext) { CompositeComponentDefinition compositeDef = new composiTecomponentdefinition (Element.gettagname (), parsercontext.extractsource (Element)); parsercontext.pushcontainingcomponent (compositedef); BeanDefinitionRegistry beanRegistry = Parsercontext.getregistry ()///Here session-registry-ref to get the custom sessionregistry, string sessionregistryid = element.getattribute (ATT_SESSION_REGISTRY_ REF); if ( ! Stringutils.hastext (Sessionregistryid)) { rootbeandefinition sessionregistry = new rootbeandefinition (Sessionregistryimpl.class); beanregistry.registerbeandefinition (beanids.session_registry, Sessionregistry); Parsercontext.registercomponent (New beancomponentdefinition (sessionregistry, beanids.session_ REGISTRY)); sessionregistryid = BeanIds.SESSION_REGISTRY; } else { //Register Default id Register the default ID as an alias so that things like session fixation filter can access it beanregistry.registeralias (Sessionregistryid, beanids.session_registry); } string registryalias = element.getattribute (ATT_ Session_registry_alias); if (StringUtils.hasText ( Registryalias)) { Beanregistry.registeralias (Sessionregistryid, registryalias); } beandefinitionbuilder filterbuilder = beandefinitionbuilder.rootbeandefinition (ConcurrentSessionFilter.class); filterbuilder.addpropertyvalue ("SessionRegistry", new runtimebeanreference (Sessionregistryid));
The
also means that when sessionregistry is initializing, spring security uses beanregistry to manage its own default bean implementation, and if you want to use custom, you need to give the appropriate configuration to replace the default. The default implementation alias is defined in the Beanids abstract class, and gets the default if it is not obtained.
public abstract class beanids { /** external alias for filterchainproxy bean, for use in web.xml files */ public static final String SPRING_SECURITY_FILTER_CHAIN = " Springsecurityfilterchain "; /** package protected as End users shouldn ' t really be using this bfpp directly */ static final String INTERCEPT_METHODS_BEAN_FACTORY_POST_PROCESSOR = "_ INTERCEPTMETHODSBEANFACTORYPP "; static final string context_source_ setting_post_processor = "_contextsettingpostprocessor"; static final String ENTRY_POINT_INJECTION_POST_PROCESSOR = "_entrypointinjectionbeanpostprocessor"; static final  string user_details_service_injection_post_processor = "_userserviceinjectionpostprocessor"; static final string session_registry_injection_post_processor = "_sessionregistryinjectionpostprocessor"; static final string filter_chain_post_processor = "_filterchainproxypostprocessor"; static final String FILTER_LIST = "_filterchainlist"; public static final String JDBC_USER_DETAILS_MANAGER = "_ Jdbcuserdetailsmanager "; public static final string user_details_service = "_userdetailsservice"; public static final string anonymous_ processing_filter = "_anonymousprocessingfilter"; public static final string anonymous_authentication_provider = "_anonymousauthenticationprovider"; public static final String BASIC_AUTHENTICATION_FILTER = "_basicauthenticationfilter"; public static final string basic_authentication_entry_point = "_ Basicauthenticationentrypoint "; public static final string session_ registry = "_sessionregistry"; public static final string concurrent_session_filter = "_concurrentsessionfilter"; So I just need to add the session-registry-ref in the configuration is good. <beans:bean id= "Sessionregistry" class= " Com.shop.core.security.support.SessionRegistryImpl " scope=" Singleton "> <beans: Property name= "CacheManager" ref= "CacheManager" /></beans:bean><bean:http Auto-config= "false" entry-point-ref= "LoginurlentrypoiNT ">...<bean:concurrent-session-control max-sessions=" 200000 " Exception-if-maximum-exceeded= "false" expired-url= "/outline.htm" session-registry-alias= "Sessionregistry" session-registry-ref= "Sessionregistry"/>...</bean:http>
Brief analysis of reasons why Spring Security custom sessionregistry does not work