title: Spring Boot with Session/Redis Serialization Error with Bad Active Directory Ldap Credentials
body: <p>Hi I am new to Spring and Java, I am trying to implement a Gateway authentication server as described in this tutorial <a href="https://spring.io/guides/tutorials/spring-security-and-angular-js/" rel="noreferrer">https://spring.io/guides/tutorials/spring-security-and-angular-js/</a></p>
  
  <p>I got everything working and then tried to implement the authentication against our company Ldap server. It works if I use a valid username and password. When I use invalid credentials the application errors. </p>
  
  <p>I am not at work so I don't have the exact error, but it is returning an ldap error (com.sun.jndi.ldap.LdapCtx) and Redis is trying to serialize it.</p>
  
  <p>Is there something I am missing in my configuration. From what I have read I think I should be looking for a way to wrap/extend the class and implement Serializable, but I am unsure of the least invasive way to do this with Spring Boot.</p>
  
  <p>Any help is greatly appreciated.</p>
  
  <p>Thanks,</p>
  
  <p>Mike Kowalski</p>
  
  <p>PS I have been working mostly in dynamic languages and frameworks until now (Javascript/Node, Php/Laravel)</p>
  
  <p>Here are what I think are the relevant parts of the Security configuration:</p>
  
  <pre><code>@Configuration
  @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
  public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http
        .formLogin()
        .defaultSuccessUrl("/")
        .loginPage("/login")
        .permitAll()
        .and()
        .logout()
        .logoutSuccessUrl("/logout")
        .permitAll();
  
  
      http
        .authorizeRequests()
          .antMatchers("/login").permitAll()
          .anyRequest().authenticated()
      .and()
        .csrf().csrfTokenRepository(csrfTokenRepository())
      .and()
        .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
    }
  
    @Override
     protected void configure(AuthenticationManagerBuilder authManagerBuilder)          throws Exception {
      authManagerBuilder
        .authenticationProvider(activeDirectoryLdapAuthenticationProvider())
          .userDetailsService(userDetailsService());
     }
  
     @Bean
     public AuthenticationManager authenticationManager() {
        return new ProviderManager(
          Arrays.asList(activeDirectoryLdapAuthenticationProvider())
        );
     }
  
     @Bean
     public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
    ActiveDirectoryLdapAuthenticationProvider provider = new     ActiveDirectoryLdapAuthenticationProvider(
      "XXX.XXX", "ldaps://XXX.XXX:636");
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        return provider;
     }
  
    private Filter csrfHeaderFilter() {
      return new OncePerRequestFilter() {
        @Override
        protected void doFilterInternal(
          HttpServletRequest request,
          HttpServletResponse response, 
          FilterChain filterChain
        ) throws ServletException, IOException 
        {
          CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
              .getName());
          if (csrf != null) {
            Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
            String token = csrf.getToken();
            if (cookie == null || token != null
                &amp;&amp; !token.equals(cookie.getValue())) {
              cookie = new Cookie("XSRF-TOKEN", token);
              cookie.setPath("/");
              response.addCookie(cookie);
            }
          }
          filterChain.doFilter(request, response);
        }
      };
    }
  
    private CsrfTokenRepository csrfTokenRepository() {
      HttpSessionCsrfTokenRepository repository = new     HttpSessionCsrfTokenRepository();
      repository.setHeaderName("X-XSRF-TOKEN");
      return repository;
    }
  
  }
  </code></pre>
  
  <p>Here is part of the error that using invalid credentials:</p>
  
  <pre><code>2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /login at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
  2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@44258b05
  2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /login at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
  2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /login at position 5 of 13 in additional filter chain; firing Filter: ''
  2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /login at position 6 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
  2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/logout'
  2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy        : /login at position 7 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
  2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/login'
  2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] w.a.UsernamePasswordAuthenticationFilter : Request is to process authentication
  2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider
  2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] ctiveDirectoryLdapAuthenticationProvider : Processing authentication request for user: admin
  2015-09-24 15:07:31.113 DEBUG 6552 --- [nio-8080-exec-3] ctiveDirectoryLdapAuthenticationProvider : Authentication for admin@countrycurtains.local failed:javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 525, vece]
  2015-09-24 15:07:31.113  INFO 6552 --- [nio-8080-exec-3] ctiveDirectoryLdapAuthenticationProvider : Active Directory authentication failed: User was not found in directory
  2015-09-24 15:07:31.114 DEBUG 6552 --- [nio-8080-exec-3] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
  2015-09-24 15:07:31.114 DEBUG 6552 --- [nio-8080-exec-3] w.a.UsernamePasswordAuthenticationFilter : Updated SecurityContextHolder to contain null Authentication
  2015-09-24 15:07:31.114 DEBUG 6552 --- [nio-8080-exec-3] w.a.UsernamePasswordAuthenticationFilter : Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@28626d9a
  2015-09-24 15:07:31.114 DEBUG 6552 --- [nio-8080-exec-3] .a.SimpleUrlAuthenticationFailureHandler : Redirecting to /login?error
  2015-09-24 15:07:31.115 DEBUG 6552 --- [nio-8080-exec-3] o.s.s.web.DefaultRedirectStrategy        : Redirecting to '/login?error'
  2015-09-24 15:07:31.115 DEBUG 6552 --- [nio-8080-exec-3] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
  2015-09-24 15:07:31.139 DEBUG 6552 --- [nio-8080-exec-3] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
  2015-09-24 15:07:31.148 ERROR 6552 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
  
  org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: com.sun.jndi.ldap.LdapCtx
          at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:52)
          at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:146)
          at org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:128)
          at org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:85)
          at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveDelta(RedisOperationsSessionRepository.java:409)
          at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.access$000(RedisOperationsSessionRepository.java:331)
          at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:211)
          at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:141)
          at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:193)
          at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:169)
          at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:127)
          at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:65)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:68)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
          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:142)
          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:518)
          at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
          at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
          at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
          at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
          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)
  Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: com.sun.jndi.ldap.LdapCtx
          at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:67)
          at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:34)
          at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:50)
          ... 40 common frames omitted
  Caused by: java.io.NotSerializableException: com.sun.jndi.ldap.LdapCtx
          at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
          at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
          at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
          at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
          at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
          at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
          at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:441)
          at java.lang.Throwable.writeObject(Throwable.java:985)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:497)
          at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
          at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
          at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
          at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
          at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
          at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:44)
          at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:62)
          ... 42 common frames omitted
  </code></pre>