Keycloak 用户操作邮件 URL 问题

问题描述 投票:0回答:1

大家好。我正在尝试使用 keycloak 执行操作邮件 API 发送用户操作邮件。

{{base_path}}/admin/realms/{{realm_name}}/users/{{user_id}}/execute-actions-email?redirect_uri={{redirect_uri}}&client_id={{client_id}}

为了启动邮件,我从我的自定义 API 之一调用用户操作 API。所以使用的基本路径是

http://localhost:8080
。因此,当发送用户操作邮件时,URL 也会变成
http://localhost:8080
,而不是可能的
https://temp.testkeycloak.in
域。

直接在自定义 API 中使用 URL

https://temp.testkeycloak.in
时的问题是我们无法调用该 API。它会出现这样的错误,

2024-04-29 10:12:17,326 INFO  [com.feathersoft.keycloak.organization.api.OrganizationController] (executor-thread-100) Exception createOrganizationUser: java.net.ConnectException
    at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:573)
    at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:123)
    at com.feathersoft.keycloak.organization.util.RequestManagement.put(RequestManagement.java:72)
    at com.feathersoft.keycloak.organization.api.MemberManagerController.sendUserActionMail(MemberManagerController.java:283)
    at com.feathersoft.keycloak.organization.api.OrganizationController.createOrganizationUser(OrganizationController.java:839)
    at com.feathersoft.keycloak.organization.api.OrganizationController$quarkusrestinvoker$createOrganizationUser_13ddb69a39990bc4e703b1568717ad6a98b5b13b.invoke(Unknown Source)
    at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
    at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
    at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
    at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:582)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
    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:840)
    Caused by: java.net.ConnectException
    at java.net.http/jdk.internal.net.http.common.Utils.toConnectException(Utils.java:1055)
    at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:198)
    at java.net.http/jdk.internal.net.http.AsyncSSLConnection.connectAsync(AsyncSSLConnection.java:56)
    at java.net.http/jdk.internal.net.http.Http2Connection.createAsync(Http2Connection.java:378)
    at java.net.http/jdk.internal.net.http.Http2ClientImpl.getConnectionFor(Http2ClientImpl.java:128)
    at java.net.http/jdk.internal.net.http.ExchangeImpl.get(ExchangeImpl.java:93)
    at java.net.http/jdk.internal.net.http.Exchange.establishExchange(Exchange.java:343)
    at java.net.http/jdk.internal.net.http.Exchange.responseAsyncImpl0(Exchange.java:475)
    at java.net.http/jdk.internal.net.http.Exchange.responseAsyncImpl(Exchange.java:380)
    at java.net.http/jdk.internal.net.http.Exchange.responseAsync(Exchange.java:372)
    at java.net.http/jdk.internal.net.http.MultiExchange.responseAsyncImpl(MultiExchange.java:408)
    at java.net.http/jdk.internal.net.http.MultiExchange.lambda$responseAsyncImpl$7(MultiExchange.java:449)
    at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934)
    at java.base/java.util.concurrent.CompletableFuture.uniHandleStage(CompletableFuture.java:950)
    at java.base/java.util.concurrent.CompletableFuture.handle(CompletableFuture.java:2340)
    at java.net.http/jdk.internal.net.http.MultiExchange.responseAsyncImpl(MultiExchange.java:439)
    at java.net.http/jdk.internal.net.http.MultiExchange.lambda$responseAsync0$2(MultiExchange.java:341)
    at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1150)
    at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1773)
    at java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:157)
    at java.base/java.util.concurrent.CompletableFuture.completeAsync(CompletableFuture.java:2673)
    at java.net.http/jdk.internal.net.http.MultiExchange.responseAsync(MultiExchange.java:294)
    at java.net.http/jdk.internal.net.http.HttpClientImpl.sendAsync(HttpClientImpl.java:654)
    at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:552)
    ... 15 more
    Caused by: java.nio.channels.UnresolvedAddressException
    at java.base/sun.nio.ch.Net.checkAddress(Net.java:149)
    at java.base/sun.nio.ch.Net.checkAddress(Net.java:157)
    at java.base/sun.nio.ch.SocketChannelImpl.checkRemote(SocketChannelImpl.java:816)
    at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:839)
    at java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$0(PlainHttpConnection.java:183)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
    at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:185)
    ... 38 more

有人可以帮我吗?有没有 SPI 可以替代这个选项?

keycloak keycloak-services keycloak-rest-api
1个回答
0
投票

我用 keycloak SPI 找到了解决方案。我们可以使用 keycloak EmailTemplateProvider 类来发送操作邮件。

使用 SPI 完成导入。

    import jakarta.ws.rs.core.UriBuilder;
    import org.keycloak.models.KeycloakContext;
    import org.keycloak.models.RealmModel;
    import org.keycloak.models.UserModel;
    import org.keycloak.email.EmailTemplateProvider;
    import org.keycloak.authentication.actiontoken.execactions.ExecuteActionsActionToken;

发送操作电子邮件的代码。

    KeycloakContext context = this.session.getContext();
    RealmModel realm = context.getRealm();
    UserModel user = this.session.users().getUserById(realm, userID);
    int validityInSecs = realm.getActionTokenGeneratedByUserLifespan();
    int absoluteExpirationInSecs = Time.currentTime() + validityInSecs;
    ExecuteActionsActionToken token = new ExecuteActionsActionToken(
            userID, user.getEmail(), absoluteExpirationInSecs, actionsList, redirectURI,
            clientId);

    UriBuilder builder = LoginActionsService.actionTokenProcessor(session.getContext().getUri());
    builder.queryParam("key", token.serialize(session, realm, session.getContext().getUri()));

    String link = builder.build(realm.getName()).toString();

    EmailTemplateProvider emailTemplateProvider = session.getProvider(EmailTemplateProvider.class);
    emailTemplateProvider
            .setRealm(realm)
            .setUser(user)
            .sendExecuteActions(link, validityInSecs);
© www.soinside.com 2019 - 2024. All rights reserved.