Skip to content
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

ClassNotFoundException: PasswordEncoder #23

Closed
SamuelBucheliZ opened this issue Jun 1, 2021 · 7 comments
Closed

ClassNotFoundException: PasswordEncoder #23

SamuelBucheliZ opened this issue Jun 1, 2021 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@SamuelBucheliZ
Copy link

SamuelBucheliZ commented Jun 1, 2021

Looking at https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/multi-tenancy I currently see the following two issues.

Running Application Fails with ClassNotFoundException for org.springframework.security.crypto.password.PasswordEncoder

At the moment, running

./gradlew bootRun

fails (for me) with


> Task :bootRun FAILED

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.0)

2021-06-01 18:26:41.133  INFO 26749 --- [           main] example.OAuth2ResourceServerApplication  : Starting OAuth2ResourceServerApplication using Java 11.0.2 on <removed> with PID 26749 (<removed>/spring-security-samples/servlet/spring-boot/java/oauth2/resource-server/multi-tenancy/build/classes/java/main started by <removed> in <removed>/spring-security-samples/servlet/spring-boot/java/oauth2/resource-server/multi-tenancy)
2021-06-01 18:26:41.135  INFO 26749 --- [           main] example.OAuth2ResourceServerApplication  : No active profile set, falling back to default profiles: default
2021-06-01 18:26:41.222  WARN 26749 --- [kground-preinit] o.s.h.c.j.Jackson2ObjectMapperBuilder    : For Jackson Kotlin classes support please add "com.fasterxml.jackson.module:jackson-module-kotlin" to the classpath
2021-06-01 18:26:41.890 ERROR 26749 --- [           main] o.s.boot.SpringApplication               : Application run failed

java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration
        at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-2.5.0.jar:2.5.0]
        at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$TrackedConditionEvaluator.shouldSkip(ConfigurationClassBeanDefinitionReader.java:489) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$TrackedConditionEvaluator.shouldSkip(ConfigurationClassBeanDefinitionReader.java:478) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:140) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:129) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:343) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:438) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:337) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1336) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1325) ~[spring-boot-2.5.0.jar:2.5.0]
        at example.OAuth2ResourceServerApplication.main(OAuth2ResourceServerApplication.java:30) ~[main/:na]
Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@4b85612c]
        at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481) ~[spring-core-5.3.7.jar:5.3.7]
        at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:358) ~[spring-core-5.3.7.jar:5.3.7]
        at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:414) ~[spring-core-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$2(AbstractAutowireCapableBeanFactory.java:747) ~[spring-beans-5.3.7.jar:5.3.7]
        at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1705) ~[na:na]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:746) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:685) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:656) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1670) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:570) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:542) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:238) ~[spring-boot-autoconfigure-2.5.0.jar:2.5.0]
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:231) ~[spring-boot-autoconfigure-2.5.0.jar:2.5.0]
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:221) ~[spring-boot-autoconfigure-2.5.0.jar:2.5.0]
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:169) ~[spring-boot-autoconfigure-2.5.0.jar:2.5.0]
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:144) ~[spring-boot-autoconfigure-2.5.0.jar:2.5.0]
        at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.5.0.jar:2.5.0]
        ... 18 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/springframework/security/crypto/password/PasswordEncoder
        at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na]
        at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3167) ~[na:na]
        at java.base/java.lang.Class.getDeclaredMethods(Class.java:2310) ~[na:na]
        at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463) ~[spring-core-5.3.7.jar:5.3.7]
        ... 34 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.security.crypto.password.PasswordEncoder
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583) ~[na:na]
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
        ... 38 common frames omitted

2021-06-01 18:26:41.906  WARN 26749 --- [           main] o.s.boot.SpringApplication               : Unable to close ApplicationContext

java.lang.IllegalStateException: Failed to introspect Class [org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@4b85612c]
        at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481) ~[spring-core-5.3.7.jar:5.3.7]
        at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:358) ~[spring-core-5.3.7.jar:5.3.7]
        at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:414) ~[spring-core-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$2(AbstractAutowireCapableBeanFactory.java:747) ~[spring-beans-5.3.7.jar:5.3.7]
        at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1705) ~[na:na]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:746) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:685) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:656) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1670) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:570) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:542) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:667) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:659) ~[spring-beans-5.3.7.jar:5.3.7]
        at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1300) ~[spring-context-5.3.7.jar:5.3.7]
        at org.springframework.boot.SpringApplication.getExitCodeFromMappedException(SpringApplication.java:890) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.getExitCodeFromException(SpringApplication.java:878) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.handleExitCode(SpringApplication.java:865) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:806) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:347) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1336) ~[spring-boot-2.5.0.jar:2.5.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1325) ~[spring-boot-2.5.0.jar:2.5.0]
        at example.OAuth2ResourceServerApplication.main(OAuth2ResourceServerApplication.java:30) ~[main/:na]
Caused by: java.lang.NoClassDefFoundError: org/springframework/security/crypto/password/PasswordEncoder
        at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na]
        at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3167) ~[na:na]
        at java.base/java.lang.Class.getDeclaredMethods(Class.java:2310) ~[na:na]
        at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463) ~[spring-core-5.3.7.jar:5.3.7]
        ... 21 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.security.crypto.password.PasswordEncoder
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583) ~[na:na]
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
        ... 25 common frames omitted


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':bootRun'.
> Process 'command '/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1

* 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

BUILD FAILED in 2s
4 actionable tasks: 1 executed, 3 up-to-date

It seems this behavior can be easily fixed adding

implementation 'org.springframework.security:spring-security-crypto'

to the dependencies block in build.gradle.

In case it seems this problem affects also other people, I would suggest adjusting the example to include this additional dependency.

Update: I also just noticed, that I have the same problem with https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/hello-security

InMemoryUserDetailsManager is Auto-Configured

Once the problem above is fixed, the application starts. However, in the log output I see

2021-06-01 18:34:39.832  INFO 26857 --- [           main] .s.s.UserDetailsServiceAutoConfiguration : 

Using generated security password: f89a4c05-3b75-4c2c-89a0-60dceba7e4ec

In my opinion, this is somewhat unexpected, as I would expect the same behavior as in the "simple", non-multi-tenant case (e.g., https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/hello-security ), where the auto-configuration is not activated (I think due to the presence of a JwtDecoder bean, but I have not fully investigated this).

I would therefore suggest to explicitly disable this auto-configuration in the multi-tenant example. Unfortunately, I'm not quite sure what the best way is to achieve this. The easiest is probably just excluding the configuration via

@SpringBootApplication(exclude = UserDetailsServiceAutoConfiguration.class)

in OAuth2ResourceServerApplication. However, I haven't checked whether this leads to any undesirable side-effects.

Related: spring-projects/spring-security#9767

@jzheaux jzheaux self-assigned this Jun 1, 2021
@jzheaux jzheaux added the bug Something isn't working label Jun 1, 2021
@jzheaux jzheaux assigned rwinch and unassigned jzheaux Jun 1, 2021
@rwinch rwinch changed the title Improvements for Java Spring Boot OAuth2 Resource-Server Multi-Tenancy Example ClassNotFoundException: PasswordEncoder Jun 1, 2021
@rwinch rwinch closed this as completed Jun 3, 2021
@rwinch rwinch reopened this Jun 3, 2021
@rwinch
Copy link
Member

rwinch commented Jun 3, 2021

Thanks for the report. This is due to the fact that Spring Boot's spring-boot-starter-security is excluding spring-security-crypto spring-projects/spring-boot@33a5c31 It will be resolved once spring-projects/spring-boot#26588 is closed.

@jzheaux Do our tests catch this problem if we are running against our SNAPSHOTs?

@rwinch rwinch closed this as completed Jun 3, 2021
@SamuelBucheliZ
Copy link
Author

@rwinch Thank you very much for the update. As a quick question (and my apologies for jamming two issues into one): do you think I should open a separate issue regarding the UserDetailsServiceAutoConfiguration question or do you consider it expected behavior?

@rwinch
Copy link
Member

rwinch commented Jun 4, 2021

That is a separate issue. I'd consider creating an issue with spring boot for it

@SamuelBucheliZ
Copy link
Author

@rwinch Thank you very much for your feedback, I have openend spring-projects/spring-boot#26766 with Spring Boot.

@BavariaBlue
Copy link

Is the current workaround still valid? (import statement mentioned by @SamuelBucheliZ)

I got the same issue when trying to run https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/webclient

I'd love love to run the sample application way before June 21 (as mentioned in !26588) in order to understand spring boot oauth2 a bit more.

Btw. If anyone knows of a good, working and non-deprecated guide on how to integrate an OAuth2 OIDC application provider (with ADFS(sic!)) in a spring boot web client, I'd be grateful for reading it :)

@jzheaux
Copy link
Contributor

jzheaux commented Jun 9, 2021

@rwinch the tests transitively include spring-security-crypto in their classpath which is why the issue doesn't manifest in the tests.

@jzheaux
Copy link
Contributor

jzheaux commented Jun 9, 2021

I'd love to run the sample application way before June 21

You can play with the samples on the 5.5.0 tag. This issue is only manifest on the most recent Spring Security snapshot.

For example this works for me:

git checkout tags/5.5.0 -b 5.5.0
./gradlew :servlet:spring-boot:java:hello-security:bootRun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants