0

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 &quot;%r&quot; %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.

+0

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

+0

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

+0

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

Répondre

0

On dirait que j'ai enfin résolu le problème. L'une des machines du cluster exécutait une version antérieure de Tomcat. Après l'avoir mis à niveau de la version v7.0.54 vers la version v7.0.69 (également mise à jour de Java), tout fonctionne correctement.