Hi I am new to Spring and Java, I am trying to implement a gateway authentication server as described in this lesson https://spring.io/guides/tutorials/spring-security-and-angular-js/
I got everything that worked, and then tried to implement authentication on our company's Ldap server. It works if I use a valid username and password. When I use the wrong credentials, application errors.
I am not working, so I have no exact error, but it returns the ldap error (com.sun.jndi.ldap.LdapCtx), and Redis is trying to serialize it.
Something I am missing in my configuration. From what I read, I think I should look for a way to wrap / extend the class and implement Serializable, but I'm not sure of the least invasive way to do this using Spring Boot.
Any help is greatly appreciated.
Thanks,
Mike Kowalski
PS I work mainly in dynamic languages ββand frameworks so far (Javascript / Node, Php / Laravel)
Here is what I consider relevant parts of a security configuration:
@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 && !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; } }
Here is the part of the error that uses invalid credentials:
2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] ossecurity.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] osswheader.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.se curity.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@ 44258b05 2015-09-24 15:07:30.564 DEBUG 6552 --- [nio-8080-exec-3] ossecurity.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] ossecurity.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] ossecurity.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] osswumatcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/logout' 2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] ossecurity.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] osswumatcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/login' 2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] waUsernamePasswordAuthenticationFilter : Request is to process authentication 2015-09-24 15:07:30.580 DEBUG 6552 --- [nio-8080-exec-3] ossauthentication.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] waUsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials 2015-09-24 15:07:31.114 DEBUG 6552 --- [nio-8080-exec-3] waUsernamePasswordAuthenticationFilter : Updated SecurityContextHolder to contain null Authentication 2015-09-24 15:07:31.114 DEBUG 6552 --- [nio-8080-exec-3] waUsernamePasswordAuthenticationFilter : Delegating to authentication failure handler org.springframework.se curity.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] ossweb.DefaultRedirectStrategy : Redirecting to '/login?error' 2015-09-24 15:07:31.115 DEBUG 6552 --- [nio-8080-exec-3] wcHttpSessionSecurityContextRepository : 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] sswcSecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed 2015-09-24 15:07:31.148 ERROR 6552 --- [nio-8080-exec-3] oaccC[.[.[/].[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