Describe the bug
When one wants to use the Argon2PasswordEncoder which is available in Spring Security the following exception is being thrown:
java.lang.NoClassDefFoundError: org/bouncycastle/crypto/params/Argon2Parameters$Builder
at org.springframework.security.crypto.argon2.Argon2PasswordEncoder.encode(Argon2PasswordEncoder.java:78) ~[spring-security-core-5.3.3.RELEASE.jar:5.3.3.RELEASE]
at eu.balev.argondemo.ArgondemoApplicationInit.run(ArgondemoApplicationInit.java:18) ~[main/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) ~[spring-boot-2.3.2.BUILD-SNAPSHOT.jar:2.3.2.BUILD-SNAPSHOT]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:779) ~[spring-boot-2.3.2.BUILD-SNAPSHOT.jar:2.3.2.BUILD-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) ~[spring-boot-2.3.2.BUILD-SNAPSHOT.jar:2.3.2.BUILD-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.2.BUILD-SNAPSHOT.jar:2.3.2.BUILD-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.2.BUILD-SNAPSHOT.jar:2.3.2.BUILD-SNAPSHOT]
at eu.balev.argondemo.ArgondemoApplication.main(ArgondemoApplication.java:10) ~[main/:na]
Caused by: java.lang.ClassNotFoundException: org.bouncycastle.crypto.params.Argon2Parameters$Builder
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]
... 8 common frames omitted
This can be mitigated by explicitly adding a dependency to bouncy castle, e.g. if you use gradle:
implementation 'org.bouncycastle:bcprov-jdk15on:1.64'
To Reproduce
For example you can define a bean and try to encode a pass word using this bean:
@Bean
public PasswordEncoder myPasswordEncoder() {
return new Argon2PasswordEncoder();
}
@Component
public class ArgondemoApplicationInit implements CommandLineRunner {
final PasswordEncoder passwordEncoder;
public ArgondemoApplicationInit(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
@Override
public void run(String... args) throws Exception {
System.out.println(passwordEncoder.encode("topsecret"));
}
}
Expected behavior
No exception is thrown and no additional dependencies are needed except the dependency to the spring security.
Sample
To reproduce clone and run:
./gradlew bootRun
Comment From: jgrandja
@luchob This behaviour is expected since BouncyCastle is declared as an optional dependency. Not all spring security deployments require BouncyCastle hence it being optional. If you are using a feature within Spring Security that requires BouncyCastle (Argon2PasswordEncoder) then you need to explicitly declare it. I'm going to close this issue since this behaviour is expected.