Skip to content

BadCredentialsException is not serializable when using LDAP Authentication #5378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
iKrushYou opened this issue May 24, 2018 · 34 comments
Closed
Assignees
Labels
in: ldap An issue in spring-security-ldap type: bug A general bug
Milestone

Comments

@iKrushYou
Copy link

Summary

When using Spring Security (using LDAP) and Spring Session (jdbc) in combination, I'm running into a serialization error only when authentication fails. When the user logs in with correct credentials, everything works as expected. Session is duplicated across all nodes. But when the user enters invalid credentials, the server throws up an exception that I'm not sure how to catch (or mitigate)

Actual Behavior

The user logs in incorrectly and this error is thrown:

Failed to convert from type [java.lang.Object] to type [byte[]] for value 'org.springframework.security.authentication.BadCredentialsException: Bad credentials'; 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

Expected Behavior

The LdapCtx object should be serialized or ignored

Configuration

		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-jdbc</artifactId>
		</dependency>

spring.session.store-type=jdbc

Version

Spring Boot Starter version 1.5.10.RELEASE

I have been redirected here from the spring session repo
spring-projects/spring-session#685

@iKrushYou
Copy link
Author

Also, on the note of LDAP, I'm looking to be able to take the error message and pass it through to the UI but I can't find any docs on that. Should I open a new issue regarding this? Thanks

@jbollacke
Copy link

I am experiencing the same issue on v2.0.5.RELEASE.

Is there any workaround for this?

@rwinch
Copy link
Member

rwinch commented Aug 22, 2018

Thanks for the report.

Also, on the note of LDAP, I'm looking to be able to take the error message and pass it through to the UI but I can't find any docs on that. Should I open a new issue regarding this? Thanks

It is generally recommended that you do not pass any details along to the UI about why authentication failed. Instead, you should give a generic message. Something like "The username/password combination you provided was not valid. Try again or click Forgot password to reset it."

You could access it via a session attribute name of WebAttributes.AUTHENTICATION_EXCEPTION, but again it is not recommended to convey anything but a generic error message to the user.

Is there any workaround for this?

I cannot think of a simple one off the top of my head at the moment. However, if someone can put a complete and minimal sample together perhaps we can come up with a fix and/or workaround.

@jbollacke
Copy link

Just investigated a little futher. But I am off for holidays now. I will try to provide a quick example or possible solution after I return.

I ended up copying ActiveDirectoryLdapAuthenticationProvider and removing .initCause on badCredentials so the BadCredentialsException won't include the com.sun.jndi.ldap.LdapCtx as quick fix for now. Shame on me :( Though the code is not in production yet

@rwinch
Copy link
Member

rwinch commented Aug 22, 2018

That seems like a reasonable workaround to me.

What is the type of Exception that is being passed into initCause?

@jbollacke
Copy link

javax.naming.AuthenticationException and resolvedObj property contains the not-serializable LdapCtx.

@iKrushYou
Copy link
Author

@rwinch I'm looking to obtain the failure reason for logging purposes and also to let the client know if he is providing incorrect credentials or of his account is locked (a common occurrence).

I did figure out how to do this, though:

@Component
public class AuthFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {

        getRedirectStrategy().sendRedirect(request, response, "/login?error=" + exception.getMessage());
    }
}
                .loginPage("/login")
                .failureUrl("/login?error")
                .permitAll()
                .failureHandler(authFailureHandler)

This was a while ago, but I believe this solution both fixes my serialization issue and helps me pass on the error message.

@jbollacke
Copy link

@iKrushYou Yeah that should do aswell because WebAttributes.AUTHENTICATION_EXCEPTION session attribute is not set in this implementation.

@rwinch
Copy link
Member

rwinch commented Aug 22, 2018

@jbollacke

javax.naming.AuthenticationException and resolvedObj property contains the not-serializable LdapCtx.

Thanks for the reply. It is surprising that is the root cause. Throwable implements Serializable, we should have some guarantees that the Exception is Serializable. It appears however, that the JDK is throwing an exception that is not Serialable

Do you have the complete stacktrace of BadCredentialsException and its causes when the problem occurs? If we are the ones throwing the Exception perhaps we can replace the original exception with Spring LDAP's NamingException since it handles the resolvedObj during serialization.

@iKrushYou
Copy link
Author

@rwinch let me see if i can remove this handler and see if I can get the stack trace for you.

@jbollacke
Copy link

javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C09042A, comment: AcceptSecurityContext error, data 52e, v3839 ]
	at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3154)
	at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3100)
	at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2886)
	at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2800)
	at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)
	at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
	at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
	at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
	at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
	at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
	at javax.naming.InitialContext.init(InitialContext.java:244)
	at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:154)
	at org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider$ContextFactory.createContext(ActiveDirectoryLdapAuthenticationProvider.java:403)
	at org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider.bindAsUser(ActiveDirectoryLdapAuthenticationProvider.java:203)
	at org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider.doAuthentication(ActiveDirectoryLdapAuthenticationProvider.java:144)
	at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:85)
	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
	at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:147)
	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

@iKrushYou
Copy link
Author

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object] to type [byte[]] for value 'org.springframework.security.authentication.BadCredentialsException: Bad credentials'; 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.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:43) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:203) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.session.jdbc.JdbcOperationsSessionRepository.serialize(JdbcOperationsSessionRepository.java:627) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.jdbc.JdbcOperationsSessionRepository.access$400(JdbcOperationsSessionRepository.java:129) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.jdbc.JdbcOperationsSessionRepository$2$3.setValues(JdbcOperationsSessionRepository.java:456) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:881) ~[spring-jdbc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:876) ~[spring-jdbc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:639) ~[spring-jdbc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:876) ~[spring-jdbc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:937) ~[spring-jdbc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.session.jdbc.JdbcOperationsSessionRepository$2.doInTransactionWithoutResult(JdbcOperationsSessionRepository.java:451) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:34) ~[spring-tx-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) ~[spring-tx-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.session.jdbc.JdbcOperationsSessionRepository.save(JdbcOperationsSessionRepository.java:417) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.jdbc.JdbcOperationsSessionRepository.save(JdbcOperationsSessionRepository.java:129) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:245) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:217) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:170) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) ~[spring-session-1.3.1.RELEASE.jar:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) ~[spring-boot-actuator-1.5.10.RELEASE.jar:1.5.10.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.27.jar:8.5.27]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
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:68) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:35) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:386) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:37) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	... 44 common frames omitted
Caused by: java.io.NotSerializableException: com.sun.jndi.ldap.LdapCtx
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:441) ~[na:1.8.0_181]
	at java.lang.Throwable.writeObject(Throwable.java:985) ~[na:1.8.0_181]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
	at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1140) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:441) ~[na:1.8.0_181]
	at java.lang.Throwable.writeObject(Throwable.java:985) ~[na:1.8.0_181]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
	at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1140) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) ~[na:1.8.0_181]
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) ~[na:1.8.0_181]
	at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:46) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:63) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
	... 47 common frames omitted

rwinch added a commit to rwinch/spring-security that referenced this issue Aug 22, 2018
@rwinch
Copy link
Member

rwinch commented Aug 22, 2018

It appears the JDK is throwing the Exception that is not Serializable because it specifies a property that is not serialiable on it. I have added a branch to my fork that attempts to resolve the issue. Can you try this and see if it fixes the issue for you?

https://github.com/rwinch/spring-security/tree/gh-5378-ldap-serialization-issue

@iKrushYou
Copy link
Author

@rwinch forgive my ignorance, but what is the easiest way to replace my maven dependency with your current branch?

@rwinch
Copy link
Member

rwinch commented Aug 22, 2018

@iKrushYou Not a problem. You would clone my repository, switch to the correct branch, and run a ./gradlew install. Then update your pom to point to 5.1.0.BUILD-SNAPSHOT.

@iKrushYou
Copy link
Author

@rwinch is that a gradle command? I can install gradle if i have to, but is there a maven command too?

@rwinch
Copy link
Member

rwinch commented Aug 22, 2018

It is a gradle command, but you don't need to install Gradle since it has the Gradle wrapper which automatically downloads the correct version of Gradle for you.

@iKrushYou
Copy link
Author

one last question.. sorry

I've got these security dependencies.. which one?

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-ldap</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

@rwinch
Copy link
Member

rwinch commented Aug 22, 2018

No problem.

The spring-security-ldap dependency is probably the most important, but you should do all of them. For Spring Boot, you can do this by specifying a property <spring-security.version>5.1.0.BUILD-SNAPSHOT</spring-security.version>.

@iKrushYou
Copy link
Author

To preface: I'm on a firewalled network

So the ./gradlew install didn't work.. it timed out

I installed gradle manually and tried gradle install
It tried downloading some other dependencies and that also timed out.. :/

@rwinch
Copy link
Member

rwinch commented Aug 23, 2018

Are you able to connect to https://repo.spring.io/ ?

@iKrushYou
Copy link
Author

My IntelliJ has proxies that should work.. I also have a proxy in terminal so I'm not sure why it's not working.

@rwinch
Copy link
Member

rwinch commented Aug 23, 2018

I'm not sure IntelliJ will use those settings. Have you tried configuring Gradle to use those settings? https://docs.gradle.org/current/userguide/build_environment.html#sec:accessing_the_web_via_a_proxy

@iKrushYou
Copy link
Author

C02X2PA8JG5H:spring-security-gh-5378-ldap-serialization-issue akrush$ gradle install

FAILURE: Build failed with an exception.

* What went wrong:
Could not resolve all files for configuration ':buildSrc:runtimeClasspath'.
> Could not resolve com.google.appengine:appengine-tools-sdk:1.4.2.
  Required by:
      project :buildSrc
   > Could not resolve com.google.appengine:appengine-tools-sdk:1.4.2.
      > Could not get resource 'https://repo.maven.apache.org/maven2/com/google/appengine/appengine-tools-sdk/1.4.2/appengine-tools-sdk-1.4.2.pom'.
         > Could not GET 'https://repo.maven.apache.org/maven2/com/google/appengine/appengine-tools-sdk/1.4.2/appengine-tools-sdk-1.4.2.pom'.
            > Connect to repo.maven.apache.org:443 [repo.maven.apache.org/151.101.184.215] failed: connect timed out
> Could not resolve emma:emma:2.0.5312.
  Required by:
      project :buildSrc
   > Could not resolve emma:emma:2.0.5312.
      > Could not get resource 'https://repo.maven.apache.org/maven2/emma/emma/2.0.5312/emma-2.0.5312.pom'.
         > Could not GET 'https://repo.maven.apache.org/maven2/emma/emma/2.0.5312/emma-2.0.5312.pom'.
            > Connect to repo.maven.apache.org:443 [repo.maven.apache.org/151.101.184.215] failed: connect timed out
> Could not resolve com.thaiopensource:trang:20091111.
  Required by:
      project :buildSrc
   > Could not resolve com.thaiopensource:trang:20091111.
      > Could not get resource 'https://repo.maven.apache.org/maven2/com/thaiopensource/trang/20091111/trang-20091111.pom'.
         > Could not GET 'https://repo.maven.apache.org/maven2/com/thaiopensource/trang/20091111/trang-20091111.pom'.
            > Connect to repo.maven.apache.org:443 [repo.maven.apache.org/151.101.184.215] failed: connect timed out
> Could not resolve net.sourceforge.saxon:saxon:9.1.0.8.
  Required by:
      project :buildSrc
   > Could not resolve net.sourceforge.saxon:saxon:9.1.0.8.
      > Could not get resource 'https://repo.maven.apache.org/maven2/net/sourceforge/saxon/saxon/9.1.0.8/saxon-9.1.0.8.pom'.
         > Could not GET 'https://repo.maven.apache.org/maven2/net/sourceforge/saxon/saxon/9.1.0.8/saxon-9.1.0.8.pom'.
            > Connect to repo.maven.apache.org:443 [repo.maven.apache.org/151.101.184.215] failed: connect timed out

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Don't think so..

@iKrushYou
Copy link
Author

iKrushYou commented Aug 23, 2018

or, i get this with ./gradlew

C02X2PA8JG5H:spring-security-gh-5378-ldap-serialization-issue akrush$ ./gradlew install
Downloading https://services.gradle.org/distributions/gradle-4.8-bin.zip

Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
	at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1964)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)
	at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
	at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
	at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
	at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
	at org.gradle.wrapper.Download.downloadInternal(Download.java:66)
	at org.gradle.wrapper.Download.download(Download.java:51)
	at org.gradle.wrapper.Install$1.call(Install.java:62)
	at org.gradle.wrapper.Install$1.call(Install.java:48)
	at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:69)
	at org.gradle.wrapper.Install.createDist(Install.java:48)
	at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:107)
	at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
	at sun.security.validator.Validator.validate(Validator.java:262)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
	at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596)
	... 20 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
	... 26 more

@rwinch
Copy link
Member

rwinch commented Aug 23, 2018

I'm not sure what to do to fix your issue since I'm not in your environment. If I were to build the jars for you, I'd publish them to repo.spring.io which is the same place the build is trying to download them from.

If you install gradle manually you can use

<install-path>/gradle install

However, all gradlew is doing is trying to download the file automatically for you. It sounds like that is failing because it is downloading Gradle and the proxy is performing a MITM which means the certificate is invalid.

@iKrushYou
Copy link
Author

sorry for all the frustration.. it sucks being on a closed environment.

I have already installed gradle and i tried to do gradle install but that didn't work. It also didn't seem like it was using the proxy so I don't know.. but if you can get it hosted as a maven dependency somewhere i could probably use that.

@rwinch
Copy link
Member

rwinch commented Aug 23, 2018

I deployed it to https://repo.spring.io/snapshot/ with the version of 5.1.0-gh-5378.BUILD-SNAPSHOT. Here is an example of one of the jars http://repo.spring.io/snapshot/org/springframework/security/spring-security-core/5.1.0-gh-5378.BUILD-SNAPSHOT/

@iKrushYou
Copy link
Author

okay i was wrong.. I don't have a proxy for maven I only have an internal mirror..

also is there an easier way to communicate instead of github comments?

@rwinch
Copy link
Member

rwinch commented Aug 23, 2018

@iKrushYou I think that is the best way. We could potentially chat on Gitter too, but it quickly becomes too much for me to handle with getting stuff done too

@iKrushYou
Copy link
Author

I totally understand, i'm working on one project right now meanwhile this is something i was trying to figure out a few months ago.

I tried adding just the jar (it did not work) but i feel like there's more to it than that. Maven probably does a whole bunch of wizardry (throughout all the different dependencies)

@rwinch
Copy link
Member

rwinch commented Aug 23, 2018

You need to update the version by specifying a property <spring-security.version>5.1.0-gh-5378.BUILD-SNAPSHOT</spring-security.version>. You also need to add the repository https://repo.spring.io/snapshot/

@jbollacke
Copy link

jbollacke commented Sep 3, 2018

@rwinch I can confirm that your bugfix works.

@rwinch rwinch self-assigned this Sep 4, 2018
@rwinch rwinch added this to the 5.1.0.RC2 milestone Sep 4, 2018
@rwinch rwinch added in: ldap An issue in spring-security-ldap type: bug A general bug labels Sep 4, 2018
@rwinch rwinch closed this as completed in 5dd55d4 Sep 4, 2018
@rwinch
Copy link
Member

rwinch commented Sep 4, 2018

Thanks for the confirmation @jbollacke! This is now fixed in master

@rwinch rwinch changed the title Serialization error of LdapCtx when using LDAP Auth and Spring Session JDBC BadCredentialsException is not serializable when using LDAP Authentication Sep 4, 2018
rwinch added a commit that referenced this issue Sep 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: ldap An issue in spring-security-ldap type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants