J'ai un problème concernant la configuration de la réplication de session Tomcat.Clustering Tomcat 7 - la réplication de session ne fonctionne pas avec la sécurité du démarrage et de la sécurité du ressort
Dans notre société, nous utilisons des conteneurs de servlets Tomcat 7 derrière Apache HTTPD 2.4.6 configurés pour l'équilibrage de charge avec mod_jk/tomcat-connecteurs 1.2.37 (fonctionnant sur CentOS 7 x64). La réplication de session fonctionne avec Tomcat Manager, ce qui signifie que si nous supprimons l'un de nos Tomcats après la connexion au gestionnaire HTML, nous n'avons pas besoin de nous connecter à nouveau (nous l'avons défini comme <distributable />
dans le fichier web.xml. voir les serveurs sont en train de découvrir avec succès les uns des autres de la catalina.log:
2017.10.06 09:25:15 [INFO] org.apache.catalina.ha.tcp.SimpleTcpCluster memberAdded: Replication member added:org.apache.catalina.tribes.membership.StaticMember[tcp://10.35.217.77:4444,10.35.217.77,4444, alive=0, securePort=-1, UDP Port=-1, id={1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 }, payload={}, command={}, domain={100 101 108 116 97 45 115 116 97 ...(12)}, ]
2017.10.06 09:25:15 [INFO] org.apache.catalina.tribes.group.interceptors.TcpFailureDetector performBasicCheck: Suspect member, confirmed alive.[org.apache.catalina.tribes.membership.StaticMember[tcp://10.35.217.77:4444,10.35.217.77,4444, alive=0, securePort=-1, UDP Port=-1, id={1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 }, payload={}, command={}, domain={100 101 108 116 97 45 115 116 97 ...(12)}, ]]
Cependant, lorsque nous déployons un échantillon printemps application de démarrage, et tuer le Tomcat dans lequel nous authentifiées un utilisateur, l'invite de connexion apparaît à nouveau nous. Nous essayons de résoudre le problème depuis longtemps et cela nous rend dingue La configuration est la suivante:
Tomcat/context.xml:
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true" />
<ResourceLink name="jdbc/postgres" global="jdbc/postgres"
type="javax.sql.DataSource" />
</Context>
Tomcat/server.xml:
<Server port="8005" shutdown="SHUTDOWN" address="10.35.217.77">
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
<Resource name="jdbc/postgres" auth="Container" type="javax.sql.DataSource"
username="postgres" password=""
url="jdbc:postgresql://127.0.0.1:5432/postgres"
driverClassName="org.postgresql.Driver"
initialSize="5" maxWait="5000"
maxActive="120" maxIdle="5"
validationQuery="select 1"
poolPreparedStatements="true".
factory="org.apache.commons.dbcp.BasicDataSourceFactory" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector address="0.0.0.0" port="8080" protocol="HTTP/1.1"
connectionTimeout="30000" redirectPort="8443"
enableLookups="false" maxPostSize="20000"
executor="tcThreadPool" />
<Connector address="10.35.217.77" port="8009" protocol="AJP/1.3"
redirectPort="8443" />
<Engine name="Catalina" defaultHost="cluster" jvmRoute="node1">
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="6" channelStartOptions="3">
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
autoBind="9" selectorTimeout="5000" maxThreads="6"
address="10.35.217.77" port="4444" />
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" />
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpPingInterceptor" />
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector" />
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor" />
<Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor">
<Member className="org.apache.catalina.tribes.membership.StaticMember" securePort="-1"
host="10.35.217.79" port="4444" domain="delta-static"
uniqueId="{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}" />
</Interceptor>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=".*\.gif;.*\.jpg;.*\.png;.*\.css" />
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve" />
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener" />
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" />
</Cluster>
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="cluster" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix="log" rotatable="false"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
L'autre server.xml est similaire, avec l'IP 0,77 et adresses .79 étant commuté (et bien sûr le uniqueId est modifié).
SpringBootApp/WebSecurityConfig.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = Logger.getLogger(WebSecurityConfig.class.getName());
@Bean
public UserDetailsContextMapperImpl contextMapper() {
return new UserDetailsContextMapperImpl();
}
@Autowired
PreferenceDao preferenceDao;
@Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(
preferenceDao.findByKey("ldap.domain").getValue(),
preferenceDao.findByKey("ldap.host").getValue()
);
logger.info("Connected to LDAP.");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
provider.setSearchFilter("(sAMAccountName={0})");
provider.setUserDetailsContextMapper(contextMapper());
return provider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("s3cr3t")
.roles("USER");
}
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests()
.antMatchers("/css/**", "/js/**", "/img/**", "/font/**", "/", "/login?logout").permitAll()
.anyRequest().hasAuthority("ROLE_USER")
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().logoutSuccessUrl("/login?logout").permitAll();
}
protected class UserDetailsContextMapperImpl implements UserDetailsContextMapper, Serializable {
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
List<GrantedAuthority> mappedAuthorities = new ArrayList<>();
mappedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new User(username, "", true, true, true, true, mappedAuthorities);
}
@Override
public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
//do nothing
}
}
}
Toute aide serait grandement appréciée.
Vous pouvez avoir la réponse à votre propre question. Votre application est-elle marquée comme «'? Jetez un oeil à cette réponse https://stackoverflow.com/a/37272352/4190848 –
jlumietu
Merci pour la réponse rapide. Oui, j'ai déjà mis exactement le même web.xml dans l'application Spring Boot. Également essayé avec un context.xml contenant l'attribut distributable = "true". – Rekviem
Etes-vous sûr que toutes les données enregistrées dans la session sont sérialisables? Avec un seul paramètre de session non sérialisable, la session entière ne sera pas si elle n'a pas pu être répliquée dans le cluster – jlumietu