Невозможно вызвать nuxeo rest api из клиента rest при интеграции с плагином аутентификации Keycloak

Я хотел интегрировать keycloak в качестве плагина аутентификации для платформы nuxeo, работающего на моем локальном компьютере.

Сведения о настройке
Версия платформы Nuxeo: 10.10 (работает на Tomcat 9)
Версия Keycloak: 6.0.1
Распространение адаптера keycloak tomcat: keycloak-tomcat8-adapter-dist

Я выполнил шаги, указанные в ссылке https://github.com/nuxeo/nuxeo/tree/master/nuxeo-services/login/nuxeo-platform-login-keycloak.
Здесь я создал плагин nuxeo-platform-login-keycloak для keycloak 6.0.1 версия.

На keycloak я установил клиент аутентификации во вновь созданной области 'demo'

Сведения о клиенте доступны в конфигурации клиента.

Я создал роль как «Участники» и добавил к ней роль администратора. Я создал пользователя «keycloakuser» и добавил в «Участники».

Когда из браузера открывается nuxeo ui, процесс аутентификации работает нормально. Он перенаправляет меня на страницу входа в keycloak с действующими учетными данными, он перенаправляет меня на nuxeo ui. Пользователь, созданный вместе с назначенной ему группой «Члены».

Сценарий ошибки
Чтобы вызвать rest api от почтальона, я настроил Oauth2 для аутентификации.
Auth url: http://localhost:8080/auth/realms/demo/протокол/openid-connect/auth
URL-адрес токена: http://localhost:8080/auth/realms/demo/protocol/openid-connect/token
Клиент: testclient
Секрет клиента: *****
Область действия: openid

Я использовал access_token, полученный с использованием потока Oauth2, чтобы вызвать API как http://localhost:8190/nuxeo/api/v1/id/document_id. Это терпит неудачу с

java.lang.ClassCastException: class org.apache.catalina.core.ApplicationHttpRequest cannot be cast to class org.apache.catalina.connector.RequestFacade (org.apache.catalina.core.ApplicationHttpRequest and org.apache.catalina.connector.RequestFacade are in unnamed module of loader java.net.URLClassLoader @39aeed2f)
    at org.nuxeo.ecm.platform.ui.web.keycloak.DeploymentResult.invokeOn(DeploymentResult.java:79) [nuxeo-platform-login-keycloak-10.10.jar:?]
    at org.nuxeo.ecm.platform.ui.web.keycloak.KeycloakAuthenticatorProvider.provide(KeycloakAuthenticatorProvider.java:56) [nuxeo-platform-login-keycloak-10.10.jar:?]
    at org.nuxeo.ecm.platform.ui.web.keycloak.KeycloakAuthenticationPlugin.handleRetrieveIdentity(KeycloakAuthenticationPlugin.java:113) [nuxeo-platform-login-keycloak-10.10.jar:?]
    at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.handleRetrieveIdentity(NuxeoAuthenticationFilter.java:1137) [nuxeo-platform-web-common-10.10.jar:?]
    at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.doFilterInternal(NuxeoAuthenticationFilter.java:548) [nuxeo-platform-web-common-10.10.jar:?]

Наблюдение:
1. Вызов запроса API не попадает в конечную точку keycloak.
2. Я попытался распечатать тип reqqest (фактически тип оболочки запроса) в обоих сценариях.
Для запроса браузера это было org.apache.catalina.connector.RequestFacade а для запроса api это было org.apache.catalina.core.ApplicationHttpRequest, которое не расширяет org.apache.catalina.connector.RequestFacade

Вопросы:
1. Отличается ли приведенное выше поведение (конец в пункте 2) в более ранних версиях tomcat от tomcat 9?
2. Является ли проблема совместимостью с версией tomcat и версией jar-адаптера keycloak?


person Rajnandini Ranbhare    schedule 13.06.2019    source источник
comment
Крест Размещен на форуме Nuxeo   -  person Ravi    schedule 14.06.2019


Ответы (1)


Поздний ответ, но может пригодиться новым читателям. Несколько месяцев назад у меня была такая же проблема. Похоже, это из-за ошибки в плагине nuxeo-platform-login-keycloak.

Я завершаю внесение следующих изменений в org.nuxeo.ecm.platform.ui.web.keycloak.DeploymentResult:

public class DeploymentResult {
    final static Logger LOGGER = LoggerFactory.getLogger(DeploymentResult.class);

    private boolean isOk;

    private static KeycloakDeployment keycloakDeployment;

    private HttpServletRequest httpServletRequest;
    private HttpServletResponse httpServletResponse;
    private Request request;
    private CatalinaHttpFacade facade;

    public DeploymentResult(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        this.httpServletRequest = httpServletRequest;
        this.httpServletResponse = httpServletResponse;
    }

    boolean isOk() {
        return isOk;
    }

    public static KeycloakDeployment getKeycloakDeployment() {
        return keycloakDeployment;
    }

    public Request getRequest() {
        return request;
    }

    public CatalinaHttpFacade getFacade() {
        return facade;
    }

    public DeploymentResult invokeOn(AdapterDeploymentContext deploymentContext) {

        // In Tomcat, a HttpServletRequest and a HttpServletResponse are wrapped in a Facades
        if (httpServletRequest instanceof RequestFacade) {
            // Received upon logout.
            request = unwrapRequest(httpServletRequest);
        } else {
            request = unwrapRequest(((ServletRequestWrapper) httpServletRequest).getRequest());
        }
        facade = new CatalinaHttpFacade(httpServletResponse, request);

        if (keycloakDeployment == null) {
            keycloakDeployment = deploymentContext.resolveDeployment(facade);
        }
        if (keycloakDeployment.isConfigured()) {
            isOk = true;
            return this;
        }
        isOk = false;
        return this;
    }

    /**
     * Get the wrapper {@link Request} hidden in a {@link ServletRequest} object
     *
     * @param servletRequest, the main ServletRequest object
     * @return the wrapper {@link Request} in {@link ServletRequest}
     */
    private Request unwrapRequest(final ServletRequest servletRequest) {
        try {
            final Field f = servletRequest.getClass().getDeclaredField("request");
            f.setAccessible(true); // grant access to (protected) field
            return (Request) f.get(servletRequest);
        } catch (final NoSuchFieldException | IllegalAccessException e) {
            LOGGER.error("Couldn't unwrap request", e);
            throw new RuntimeException(e);
        } catch (final Exception e) {
            LOGGER.error("Couldn't unwrap request", e);
            throw e;
        }
    }
}

После создания и развертывания плагина с этими изменениями мне было разрешено вызывать REST API Nuxeo с аутентификацией на предъявителя, используя токен доступа, полученный через Keycloak.

Заявление об ограничении ответственности: я сосредоточился на том, чтобы он работал, а не на чистоте ...

person oysteinr    schedule 23.08.2019