Quarkus: Как обеспечить WebSocket при использовании keycloak / oidcJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Quarkus: Как обеспечить WebSocket при использовании keycloak / oidc

Сообщение Anonymous »

Я прошел много кроличьих дыр и не могу заставить это работать. Я надеюсь, что кто-то может мне помочь.

Код: Выделить всё

@Path("/api")
public class MyResource {
@Inject
SecurityIdentity securityIdentity;

@Inject
JsonWebToken jwt;

@GET
@Path("/mydata")
@RolesAllowed("user")
@NoCache
public Uni getMyData(Request request) {
// Get a claim from the Keycloak JWT
String mySpecialClaim = (String) jwt.claim("myCustomClaim").get();

// Do some work...
String resJson = "{result of work here}";

return Uni.createFrom().item(resJson)
.onItem()
.transform(item -> item != "" ? Response.ok(item) : Response.status(Response.Status.NO_CONTENT))
.onItem()
.transform(Response.ResponseBuilder::build);
}
}
< /code>
Токен доступа предоставляется клиентским приложением, которое управляет аутентификацией KeyCloak и который отправляет запрос API с токеном предъявителя. Стандартные вещи, все работают. : -) < /p>
Теперь я хочу сделать что -то похожее с конечной точкой WebSocket. Этот пост в Quarkus github Выпуска:
https://github.com/quarkusio/quarkus/issues/29919
Я кодировал это в соответствии с примером кода в посте. Регистрация показывает, как реагирующие маршрут 
и WebSocketSecurityConfigurator вызываются, и Access_token от клиента JS Websocket присутствует и, по -видимому, обрабатывается процессами безопасности Quarkus по умолчанию, как это происходит для конечных точек REST. Все хорошо.
Отсутствующая часть заключается в том, как кодировать методы OnoPen () и onMessage () в моей конечной точке WebSocket, поэтому они безопасны, реактивны, и я могу получить доступ к JWT, чтобы получить необходимые претензии, которые мне нужны. Я добавил то, что мне нужно, мне нужно в соответствии с образцом ниже.

Код: Выделить всё

@Authenticated
@ServerEndpoint(
value ="/ws",
configurator = WebSocketSecurityConfigurator.class
)
public class WebSocket {
@Inject
UserInfo userInfo;
// ...
}
< /code>
мои дополнения: < /p>
@Authenticated
@ServerEndpoint(
value ="/services/{clientid}",
configurator = WebSocketSecurityConfigurator.class
)

public class WebSocket {
@Inject
SecurityIdentity securityIdentity;

@Inject
JsonWebToken jwt;

@Inject
UserInfo userInfo;

@OnOpen
@RolesAllowed("user") // Is this possible here? Or do I use the JWT and test myself?
public void onOpen(Session session, @PathParam("clientid") String clientid) {
// Get a claim from the Keycloak JWT
String mySpecialClaim = (String) jwt.claim("myCustomClaim").get();

// Do some setup work...
// eg cache the session in a map, etc
}

@OnMessage
public void onMessage(String message, @PathParam("clientid") String clientid) {
// Get a claim from the Keycloak JWT
String myOtherSpecialClaim = (String) jwt.claim("myOtherCustomClaim").get();

// Do some work using the message...
String someMessage = "tell the world";

// Broadcast something ...
myBroadcastFunction(someMessage);
}
}
В небезопасной версии onopen () и onmessage () Методы возвращают void Потому что, конечно, в отличие от конечной точки REST, один транслирует результат вместо того, чтобы возвращать его. Если у меня есть только метод OnoPen (), и кодируйте его так: < /p>

Код: Выделить всё

@OnOpen
public void onOpen(Session session, @PathParam("clientid") String clientid) {
Log.info("websocket onOpen session=" + session.getId());
}
< /code>
Это бросает: < /p>
Unhandled error in annotated endpoint org.flowt.orgserver.gateway.WebSocketGateway_Subclass@732f20f8

java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException:

io.quarkus.runtime.BlockingOperationNotAllowedException: Blocking security check attempted in code running on the event loop.
Make the secured method return an async type, i.e.  Uni, Multi or CompletionStage,
or use an authentication mechanism that sets the SecurityIdentity in a blocking manner prior to delegating the call
< /code>
Я хотел бы не блокировать цикл событий, поэтому первое предложение является предпочтительным. < /p>
Но как мне это кодировать? Претензии мне нужны? Я думаю, что я не первый, кто должен сделать это, и должен быть какой -то шаблон для реализации. Документы Quarkus молчат об этом. />  Чтобы разрешить блокирующее исключение, документы Quarkus здесь говорят < /p>
To work around this you need to @Inject an instance
of io.quarkus.security.identity.CurrentIdentityAssociation,
and call the Uni getDeferredIdentity(); method.
You can then subscribe to the resulting Uni and will be
notified when authentication is complete and the identity
is available.
< /code>
Я не могу понять, как реализовать эту инструкцию. Отладка в коде Quarkus Я вижу, что мой access_token обрабатывается, пользователь извлекается из KeyCloak, но отложенная идентичность не устанавливается. Поэтому OnoPen () 
никогда не работает.package org.flowt.orgserver.gateway;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

import javax.websocket.Session;
import javax.websocket.OnOpen;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import io.quarkus.logging.Log;
import io.quarkus.security.Authenticated;
import io.quarkus.security.identity.CurrentIdentityAssociation;
import io.quarkus.security.identity.SecurityIdentity;

import io.smallrye.mutiny.Uni;

@ApplicationScoped
@Authenticated
@ServerEndpoint(value = "/services/{clientid}", configurator = WebSocketSecurityConfigurator.class)
public class WebSocketGateway {

@Inject
SecurityIdentity securityIdentity;

@Inject
CurrentIdentityAssociation identities;

@OnOpen
public Uni onOpen(Session session, @PathParam("clientid") String clientid) {
// This never runs
Log.info("=========================== onOpen session=" + session.getId());

return identities.getDeferredIdentity()
.onItem()
.transformToUni(identity -> {
// Just to see if we reach here
Log.info("identity=" + identity.toString());
return Uni.createFrom().voidItem();
});
}
}

< /code>
и просто для повторного завершения: конечные точки REST в этом же приложении для той же зарегистрированной работы пользователя отлично работают. < /p>
Спасибо,
murray < /p>

Подробнее здесь: https://stackoverflow.com/questions/751 ... cloak-oidc
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»