在JAR文件中添加外部JAR依赖关系
Backgorund:我正在尝试为我的旧应用程序添加USERSTORAGESPI,以便我们可以使用现有的用户凭据登录。我遵循此教程,示例应用程序的完整源代码在这里。
此应用程序正在存储明文密码,并直接比较它们。但是,我的旧数据库以加密格式存储密码。为了测试示例用户,我将凭据以bcrypt格式存储,并且在我的CustomuserSerstorageProvider类中覆盖了以下方法(ISVALID(...))。
方法1:
public class CustomUserStorageProvider implements UserStorageProvider,
UserLookupProvider,
CredentialInputValidator,
UserQueryProvider {
....
@Override
public boolean isValid(RealmModel realm, UserModel user, CredentialInput credentialInput) {
log.info("[I57] isValid(realm={},user={},credentialInput.type={})",realm.getName(), user.getUsername(), credentialInput.getType());
if( !this.supportsCredentialType(credentialInput.getType())) {
return false;
}
StorageId sid = new StorageId(user.getId());
String username = sid.getExternalId();
try ( Connection c = DbUtil.getConnection(this.model)) {
log.info("Username to query :: " + username);
PreparedStatement st = c.prepareStatement("select password from users where username = ?");
st.setString(1, username);
st.execute();
ResultSet rs = st.getResultSet();
log.info("RS " + rs);
if ( rs.next()) {
String pwd = rs.getString(1);
log.info("Password coming from query :: " + pwd);
log.info("Password coming from user input :: " + credentialInput.getChallengeResponse());
PasswordEncoder enc = new BCryptPasswordEncoder();
log.info(" enc.matches(pwd, credentialInput.getChallengeResponse()) " + enc.matches(pwd, credentialInput.getChallengeResponse()));
return enc.matches(pwd, credentialInput.getChallengeResponse());
}
else {
return false;
}
}
catch(SQLException ex) {
throw new RuntimeException("Database error:" + ex.getMessage(),ex);
}
}
}
当我将罐子放入相关路径时,KeyCloak可以阅读自定义提供商。我还可以看到,KeyCloak正在显示此新数据库中的所有导入用户,但是,在代码试图比较密码时,我在KeyCloak日志中获得以下例外。
2022-06-24 15:53:30,566 INFO [com.test.spi.provider.CustomUserStorageProvider] (executor-thread-2) RS org.postgresql.jdbc.PgResultSet@75dadacb
2022-06-24 15:53:30,566 INFO [com.test.spi.provider.CustomUserStorageProvider] (executor-thread-2) Password coming from query :: $2a$12$rrtl/vDlCCF0cK0aKu5H6uW30B4fp9cIrTQlHPMayQTR9ToZicEoW
2022-06-24 15:53:30,566 INFO [com.test.spi.provider.CustomUserStorageProvider] (executor-thread-2) Password coming from user input :: test
2022-06-24 15:53:30,567 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-2) Uncaught server error: java.lang.NoClassDefFoundError: org/springframework/security/crypto/password/PasswordEncoder
at com.test.spi.provider.CustomUserStorageProvider.isValid(CustomUserStorageProvider.java:147)
at org.keycloak.credential.UserCredentialStoreManager.lambda$validate$4(UserCredentialStoreManager.java:164)
at java.base/java.util.Collection.removeIf(Collection.java:576)
at org.keycloak.credential.UserCredentialStoreManager.validate(UserCredentialStoreManager.java:164)
at org.keycloak.credential.UserCredentialStoreManager.isValid(UserCredentialStoreManager.java:151)
at org.keycloak.credential.UserCredentialStoreManager.isValid(UserCredentialStoreManager.java:110)
at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.validatePassword(AbstractUsernameFormAuthenticator.java:229)
at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.validateUserAndPassword(AbstractUsernameFormAuthenticator.java:150)
at org.keycloak.authentication.authenticators.browser.UsernamePasswordForm.validateForm(UsernamePasswordForm.java:55)
at org.keycloak.authentication.authenticators.browser.UsernamePasswordForm.action(UsernamePasswordForm.java:48)
at org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:169)
at org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:990)
at org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:321)
at org.keycloak.services.resources.LoginActionsService.processAuthentication(LoginActionsService.java:292)
at org.keycloak.services.resources.LoginActionsService.authenticate(LoginActionsService.java:276)
at org.keycloak.services.resources.LoginActionsService.authenticateForm(LoginActionsService.java:349)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:660)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:524)
at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:474)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:476)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:434)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:192)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:141)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:32)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:151)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:82)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:42)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:67)
at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:55)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:380)
at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:358)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
at org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter.lambda$createBlockingHandler$1(QuarkusRequestFilter.java:71)
at io.vertx.core.impl.ContextImpl.lambda$null$0(ContextImpl.java:159)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)
at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$1(ContextImpl.java:157)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$13.runWith(VertxCoreRecorder.java:543)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.ClassNotFoundException: org.springframework.security.crypto.password.PasswordEncoder
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
at io.quarkus.bootstrap.runner.RunnerClassLoader.loadClass(RunnerClassLoader.java:107)
at io.quarkus.bootstrap.runner.RunnerClassLoader.loadClass(RunnerClassLoader.java:57)
... 65 more
我还尝试在启动应用程序中添加passwordEncoder作为bean,并将其添加为CustomuSerstorageProvider类中的自动依赖项,但我得到了同样的例外。
方法2:
@SpringBootApplication
public class SpiApplication {
public static void main(String[] args) {
SpringApplication.run(SpiApplication.class, args);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
-----
@Service
public class CustomUserStorageProvider implements UserStorageProvider,
UserLookupProvider,
CredentialInputValidator,
UserQueryProvider {
@Autowired
PasswordEncoder enc ;
我的pom.xml依赖关系在这里:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>18.0.0</version>
</dependency>
<!-- User Storage SPI dependency -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi</artifactId>
<version>18.0.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi</artifactId>
<version>18.0.0</version>
</dependency>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
我正在使用此命令来生成JAR文件并将其保存在keyCloak-bloak-bloak-bloak-18.0.0/ providers/ package中。
mvn package
请以正确的方法为我提供帮助。我也在这个论坛上介绍了几篇博客文章和问题,但没有获得适当的解决方案。 tia。
主要问题: 我什至在Eclipse中设置了此项目,并尝试将项目导出为JAR文件(可运行的jar/jar两者)。产生的远罐子的尺寸很大。 32 MB而不是由Shade插件创建的16KB,但例外保持不变。为什么这种依赖性未在JAR的类Pather中添加?我无法使用此JAR添加ClassPath的第三方应用程序,因此必须将其嵌入最终罐子中。请帮忙。我花了很多时间,我跑到了新的解决方法上进行尝试。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
值得庆幸的是,我找到了这篇文章,对我有用。
https:// github。 com/keycloak/keycloak/esseage/10230
要总结,
添加范围为
提供的
for keycloak,login,postgres或keycloak可能已经拥有的任何依赖项。这就是我更新的Maven的样子,org.keycloak
KeyCloak-Server-Spi
$ {keycloak.version}
假如
org.postgresql
Postgresql
42.3.6
假如
使用Maven Assembly插件并使用以下命令执行它。该。命令:
MVN清洁编译组件:单
插件:
上面的2个修改,修复了我的东西。
Thankfully I found this post and it worked for me.
https://github.com/keycloak/keycloak/issues/10230
To summarize,
Add scope as
provided
for keycloak, login, Postgres, or any dependencies which keycloak might already have. This is how my updated maven looks like,org.keycloak
keycloak-server-spi
${keycloak.version}
provided
org.postgresql
postgresql
42.3.6
provided
Utilize the maven assembly plugin and execute it using the below command. Helpful post for that another answer. Command :
mvn clean compile assembly:single
Plugin :
Above 2 modifications, repaired my thing.