1

Hazecastを使用したSpringセッションを使用するSpringブートアプリケーションがあります。アプリケーションは、Spring Securityを使用してActive Directoryで認証します。ユーザーが無効な資格情報を使用してログインしようとすると、シリアル化のエラーがスローされます。これは、Redisのと別の問題(Spring Boot with Session/Redis Serialization Error with Bad Active Directory Ldap Credentials)と同じように見えるHazelcastを使用したSpringブートアプリケーションActive Directoryログイン失敗のバックエンドSpringセッションのシリアライゼーション例外

com.hazelcast.nio.serialization.HazelcastSerializationException: java.io.NotSerializableException: com.sun.jndi.ldap.LdapCtx 
     at com.hazelcast.nio.serialization.SerializationServiceImpl.handleException(SerializationServiceImpl.java:380) 
     at com.hazelcast.nio.serialization.SerializationServiceImpl.toData(SerializationServiceImpl.java:235) 
     at com.hazelcast.nio.serialization.SerializationServiceImpl.toData(SerializationServiceImpl.java:207) 
     at com.hazelcast.map.impl.MapServiceContextImpl.toData(MapServiceContextImpl.java:338) 
     at com.hazelcast.map.impl.proxy.MapProxySupport.toData(MapProxySupport.java:1160) 
     at com.hazelcast.map.impl.proxy.MapProxyImpl.put(MapProxyImpl.java:96) 
     at org.springframework.session.hazelcast.config.annotation.web.http.HazelcastHttpSessionConfiguration$ExpiringSessionMap.put(HazelcastHttpSessionConfiguration.java:112) 
     at org.springframework.session.hazelcast.config.annotation.web.http.HazelcastHttpSessionConfiguration$ExpiringSessionMap.put(HazelcastHttpSessionConfiguration.java:102) 
     at org.springframework.session.MapSessionRepository.save(MapSessionRepository.java:72) 
     at org.springframework.session.MapSessionRepository.save(MapSessionRepository.java:36) 
     at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:194) 
     at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:170) 
     at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:128) 
     at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:65) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
     at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) 
     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
     at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103) 
     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) 
     at org.apache.coyote.ajp.AbstractAjpProcessor.process(AbstractAjpProcessor.java:868) 
     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) 
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1502) 
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1458) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
     at java.lang.Thread.run(Thread.java:745) 

、しかし、同様のメカニズムがあるように表示されません。 SpringセッションのRedisのためのHazelcastセッションマッピングの直列化を制御します。

HazelcastHttpSessionConfigurationは実際には拡張に適していないようで、理想的ではないように思われます。したがって、私たちがそうでないようなクリーンな方法があるようです見て。

ExpiringSessionMapになるようにHazelcastHttpSessionConfigurationを拡張して、LdapCtxを削除してからシリアル化を試みます。これは、HazelcastHttpSessionConfigurationがコードの重複を必要とするので、実際には拡張に自己貸与するものではないため、理想的ではないようです。

解決方法はありますか?

@Configuration 
public class CustomHazelcastHttpSessionMapConfiguration extends HazelcastHttpSessionConfiguration{ 

    private String sessionMapName = "spring:session:sessions"; 
    private int maxInactiveIntervalInSeconds = 1800; 

    @Bean 
    public SessionRepository<ExpiringSession> sessionRepository(
      HazelcastInstance hazelcastInstance, SessionEntryListener sessionListener) { 
     super.sessionRepository(hazelcastInstance, sessionListener); 

     MapSessionRepository sessionRepository = new MapSessionRepository(
       new CustomExpiringSessionMap(hazelcastInstance.getMap(this.sessionMapName))); 
     sessionRepository 
       .setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds); 

     return sessionRepository; 
    } 

    @Override 
    public void setSessionMapName(String sessionMapName) { 
     this.sessionMapName = sessionMapName; 
     super.setSessionMapName(sessionMapName); 
    } 

    @Override 
    public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) { 
     this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; 
     super.setMaxInactiveIntervalInSeconds(maxInactiveIntervalInSeconds); 
    } 

    static class CustomExpiringSessionMap implements Map<String, ExpiringSession> { 
     private IMap<String, ExpiringSession> delegate; 

     CustomExpiringSessionMap(IMap<String, ExpiringSession> delegate) { 
      this.delegate = delegate; 
     } 

     public ExpiringSession put(String key, ExpiringSession value) { 
      if (value == null) { 
       return this.delegate.put(key, value); 
      } 
      for (String attrName : value.getAttributeNames()) { 
       Object attrVal = value.getAttribute(attrName); 
       // Don't serialize LdapCtx in a BadCredentialsException 
       if (attrVal instanceof BadCredentialsException && 
         ((BadCredentialsException) attrVal).getCause() != null && 
         ((BadCredentialsException) attrVal).getCause() instanceof ActiveDirectoryAuthenticationException && 
         ((BadCredentialsException) attrVal).getCause().getCause() != null && 
         ((BadCredentialsException) attrVal).getCause().getCause() instanceof javax.naming.AuthenticationException) { 
        ((javax.naming.AuthenticationException) ((BadCredentialsException) attrVal).getCause().getCause()).setResolvedObj(null); 
       } 
      } 
      return this.delegate.put(key, value, value.getMaxInactiveIntervalInSeconds(), 
        TimeUnit.SECONDS); 
     } 

    /*... copy and paste of the rest of ExpiringSessionMap */ 
    } 
} 

答えて

0

問題が発生しているオブジェクトにはcustom serializationを設定する必要があります。

このようにして、SpringセッションのHazelcast設定を拡張/複製せずに、Hazelcast設定の問題を解決できます。

+0

ありがとうございました。これはかなりクリーンなものでした。 ExpiringSessionのカスタムシリアライザは、シリアライズされているルートオブジェクトで実装されており、シンプルなものになります。 –

0

クリーナーソリューションはtransient-attributesです。

Webフィルタを使用している場合は、プロパティのリストを渡して動作を制御できます。このフィルタは、シリアライゼーションから除外する属性名のカンマ区切りリストです。

詳細情報が必要な場合は私にメールしてください。

関連する問題