В этом руководстве вы узнаете, как настроить шаблон приложения на основе Vert.x (Java) в качестве бэкэнда и VueJs в качестве внешнего интерфейса с упором на аутентификацию пользователя против Keycloak через OAuth2. После входа пользователя в систему приложение vertx-vue-keycloak также демонстрирует, как запрашивать серверную часть Vert.x, отправлять данные (мутации) и как работает публикация / подписка между Vert.x и VueJS.

Код e2e для этой статьи размещен на GH здесь.

Шаг 1 - Подготовка к работе

Установить KeyCloak

В этом примере мы собираемся использовать Keycloak в качестве поставщика управления аутентификацией и авторизацией. Keycloak - это предложение RedHat для управления идентификацией и доступом с открытым исходным кодом, которое обеспечивает OAuth2 и многое другое. Keycloak поставляется с консолью веб-администратора для администрирования сервера. Мы легко можем запустить его на основе докера:

docker run -d — name keycloak -p 38080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin -e KEYCLOAK_LOGLEVEL=DEBUG jboss/keycloak

После запуска этого контейнера консоль администратора Keycloak будет доступна по адресу http://127.0.0.1:38080. Помните о версии Keycloak - на момент написания этой статьи она была 4.5.0.Final, поэтому пользовательский интерфейс может немного отличаться от более новых или более ранних версий.

Создайте учетные данные клиента Keycloak

Для приложения Vert.x, которое мы собираемся разработать, нам понадобится зарегистрированный клиент в Keycloak. Заполните форму указанными выделенными значениями:

Сохраните это, откройте и проверьте только что созданный клиентский объект vertx-account:

Мы вернемся к этой странице, в частности к информации на вкладке Учетные данные, позже, когда мы встроим данные клиента в код vertx.

Создать роли

На вкладке «Роли» на левой боковой панели в Keycloak создайте две примерные роли: modify-account и view-account:

Создать пользователя

На вкладке «Управление пользователями» создайте нового пользователя, дайте ему имя пользователя testuser и адрес электронной почты [email protected] и сохраните его:

По-прежнему находясь на странице только что созданных пользователей, перейдите на вкладку «Учетные данные» и установите для этого пользователя пароль test. Также снимите флажок Временный и нажмите кнопку Сбросить пароль. Имейте в виду: поведение этого пользовательского интерфейса немного странное. Когда вы нажимаете эту кнопку, флаг Временный снова становится истинным, но игнорируйте это. Введенный вами пароль должен быть установлен правильно.

Перейдите на вкладку Сопоставление ролей и назначьте только что созданные роли modify-account и view-account этому пользователю:

На этом настройка Keycloak завершена. Поздравляю! Теперь мы готовы работать над нашим сервером vert.x и интерфейсом VueJS.

Более подробную информацию о настройке Keycloak и его настройке для Vert.x можно найти в этой замечательной статье, которую я также использовал в качестве источника для приведенных выше инструкций (спасибо Петру Минковскому) .

Шаг 2 - Создайте бэкэнд Vert.x и Frontend VueJs

Я использовал Eclipse для создания простого проекта Maven (без выбора архива) и оттуда добавил vertx в список зависимостей в pom.xml. На момент написания этой статьи vertx находился на версии 3.5.4.

Клонируйте следующий репозиторий (включая исходный код для этой статьи):



git clone https://github.com/vertx-stack/vertx-vue-keycloak.git

Создать файл хранилища ключей

Возможно, вы захотите выполнить любую процедуру, которую сочтете подходящей, чтобы создать правильную цепочку сертификатов и преобразовать ее в формат jks. Пример, который я привожу здесь, основан на самозаверяющем сертификате, и он отлично работает как в локальной, так и в тестовой среде. Репозиторий, который вы только что клонировали, поставляется с файлом, поэтому вы можете пропустить этот раздел. Для производства необходимо получить сертификат, подписанный ЦС (бесплатный, например, от LetsEncrypt).

Выполните следующую команду OpenSSL, чтобы сгенерировать свой закрытый ключ и открытый сертификат. Используйте «testpassword» в качестве пароля и оставьте все значения по умолчанию (нажимайте Enter, пока не закончите):

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365

Просмотрите файл сертификата:

openssl x509 -text -noout -in cert.pem

Объедините свой ключ и сертификат в пакете PKCS # 12 (P12), а в качестве пароля экспорта снова используйте «testpassword»:

openssl pkcs12 -inkey key.pem -in cert.pem -export -out certificate.p12

Преобразуйте его в файл JKS. Используйте «testpassword» в качестве пароля целевого хранилища ключей:

keytool -importkeystore -srckeystore certificate.p12 -srcstoretype pkcs12 -destkeystore test.jks -deststoretype jks

Теперь у нас есть хранилище сертификатов в test.jks, готовое к использованию vert.x для защиты HTTPS-соединения. Этот файл также поставляется с только что клонированным репозиторием.

Знакомство с приложением vertx-vue-keycloak

Приложение содержит как исходные коды vertx для серверной части, так и код внешнего интерфейса на основе VueJS.

В Backend (src / main / java) MainVerticle.java является основной точкой входа. Это вершина Vertx, которая создает сервер HTTP / HTTPS, настраивает различные маршруты, предоставляет конечную точку / login, которая интегрируется с Keycloak, и, наконец, предоставляет конечные точки API для нашего внешнего интерфейса.

Frontend (размещенный в src / main / frontend) - это обычный интерфейс VueJS, созданный с помощью VueJS CLI. Он содержит ресурсы, библиотеки и компоненты.

Шаг 3 - Интеграция с KeyCloak

Откройте src / main / java / backend / MainVerticle.java и проверьте метод createHttpServerAndRoutes:

JsonObject keycloakJson = new JsonObject()
  .put("realm", "master") 
  .put("realm-public-key", "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZeGGDeEHmmUN4/UXh2gQD0yZEZirprsrdYK7GfcE1+QF9yfYfBrIv5cQUssFQKISVpbbLcoqYolsxcOvDyVFSQedHRsumOzqNZK38RHkidPMPrSNof5C3iMIHuXOCv/6exnLZvVoeYmkq42davYEz1tpSWzkZnlUMbRZFs1CfzLMM2rsAJWsO1/5zbDm0JhFl7EFUsTki72ihac1Q5zUUSFyf1jKUEkL7rrkYINjgAaQKktE8pnubc3Y44F5llY4YyU9/bqUWqMYDx868oiDcnoBpGGd4QrUMlbULZZLRqqUKK6iG1kHxDCJQ9gaCiJoELyAqXjnnO28OODQhxMHQIDAQAB") 
  
  .put("auth-server-url", "http://127.0.0.1:38080/auth")
  .put("ssl-required", "external")
  .put("resource", "vertx-account")
  .put("credentials", new JsonObject()
    . put("secret", "0c22e587-2ccb-4dd3-b017-5ff6a903891b")); 
OAuth2Auth oauth2 = KeycloakAuth.create(vertx, OAuth2FlowType.PASSWORD, keycloakJson);

Получите область и настоящий открытый ключ из консоли администратора Keycloak. Чтобы получить ключ, нажмите кнопку «Открытый ключ» на вкладке Ключи в главной области:

В качестве ресурса включите ранее созданный клиент vertx-account. В качестве учетных данных перейдите к нему в меню «Клиенты» ›vertx-account› Вкладка «Учетные данные» и скопируйте оттуда Секрет:

В качестве OAuth2FlowType мы собираемся выбрать ПАРОЛЬ, представляющий Поток учетных данных пароля. Более подробную информацию о OAuthFlows можно найти здесь.

Теперь мы можем определить маршрут / login для обработки фактического входа в систему:

Теперь мы можем запустить наш первый тест Vertx Backend, запустив программу запуска vert.x. Используя Postman, теперь мы можем запустить аутентификацию первого пользователя через POST для 127.0.0.1:8080/login (наш сервер vertx с маршрутом / login). В теле мы выбираем необработанные данные и вводим следующий объект JSON:

{
  "username":"testuser", 
  "password":"test", 
  "scope":"modify-account view-account"
}

Нажмите Отправить в Postman и отправьте это на наш сервер vertx:

Результат на сервере будет выглядеть следующим образом. Это означает, что мы успешно нашли пользователя «testuser» на Keycloak. Молодец!

Аутентифицируйтесь с помощью нашего веб-интерфейса

Теперь, когда у нас есть базовая аутентификация и мы протестировали ее с помощью Postman, пришло время интегрировать с ней наше приложение Frontend. Forntend находится по адресу src / main / frontend. Для этого запустите быструю установку зависимостей с помощью yarn и, наконец, запустите ее с помощью yarn dev. Подробнее здесь.

Теперь интерфейс будет запущен на localhost: 8081. Он будет представлять довольно простую страницу входа (для ее оформления использовался бутстрап):

Я не буду вдаваться в подробности этого приложения. Для получения дополнительной информации о том, как это было создано, ознакомьтесь с этой замечательной статьей от Paweł J. Wal.

Единственное, что нам нужно изменить, это настроить CORS на стороне Vert.x, чтобы убедиться, что Frontend может с ним взаимодействовать.

Теперь вы готовы аутентифицировать пользователя из приложения VueJS Frontend на вашем сервере Vert.x. При входе в систему с помощью testuser: test вы попадете в защищенное пространство вашего приложения:

Поздравляем, теперь у вас есть довольно удобный способ войти в приложение VueJS, работающее с API Vert.x и сервером аутентификации, интегрированным с Keycloak.

Шаг 4 - интеграция логики запроса и обновления данных

В качестве примера мы собираемся реализовать очень простую систему управления сообщениями, которая выглядит примерно так:

Интерфейс и части интеграции eventbus в этом примере были вдохновлены vertx-examples проектом Mateusz Parzonka на GitHub - спасибо за это!

Предлагаемая процедура в этом примере заключается в использовании стандартных конечных точек сообщений, производителей и потребителей на Vertx EventBus для полностью сложной схемы взаимодействия клиент / сервер, включая запросы, изменения данных и публикацию / подписку. Идея довольно проста:

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

На стороне Frontend мы собираемся создать сервис vertx eventbus, который будет использовать vertx3-eventbus-client. Основными методами здесь являются callApi и subscribe (дополнительные сведения о pubsub см. В шаге 5):

Чтобы получить, удалить и создать новое сообщение, проверьте компонент Home.vue, в частности использование службы eventbus из utils / eventbus:

В результате теперь вы можете использовать этот пользовательский интерфейс для получения массива известных сообщений от серверной части, создания новых сообщений и их удаления. Пока все хорошо, но подождите минутку: что на самом деле происходит с другими клиентами, которые используют то же приложение параллельно со мной? Давайте наконец погрузимся в PubSub ...

Шаг 5 - интеграция публикации и подписки

Мы уже видели, что серверная часть публикует полный массив сообщений на Vertx EventBus при каждом обновлении (что немного излишне, но давайте примем это для этого примера). Каким образом фронтенд может наконец уловить эти обновления?

К счастью, Vertx EventBus (который основан на SockJS) позволяет нам подписывать клиентов на каналы, которые могут поддерживаться любым другим клиентом (связь c2c) или также с сервера.

Наша служба eventBus предоставляет функцию для подписки на такой канал (см. Код выше). Это снова используется в компоненте Home.vue для фиксации изменений в массиве сообщений и количестве подключений, которыми управляет сервер vertx, следующим образом:

Здесь мы собираем сообщения, поступающие из каналов : pubsub / connections и : pubsub / messages, и отправляем входящие данные во внешний интерфейс. Это позволяет поддерживать синхронизацию нескольких браузеров, которые запускают одно и то же приложение, через vertx EventBus.

Ограничения

Одним из самых больших ограничений этого примера является установка серверной части vertx. В частности, безопасность на Vertx Eventbus еще не настроена, поскольку мы не проверяем, действительно ли пользователь, вызывающий API, аутентифицирован на сервере. Так что не используйте этот код для производственных приложений, не работая над этим.

Другой аспект заключается в том, что EventBus, а также обработчик / login на Backend по-прежнему работают через HTTP. Имеющееся перенаправление на HTTPS-код относится только к статическим ресурсам, а не к EventBus, насколько я тестировал с ограниченным временем. Я полагаю, поскольку мы на самом деле не обслуживаем статический HTML-контент через vertx, имеет смысл полностью отключить HTTP-сервер и просто перейти на HTTPS.

Наконец, сертификат HTTPS был самоподписанным, и, конечно же, вы не хотите использовать его для серьезного использования за пределами localhost. Получите сертификат, подписанный ЦС (например, от LetsEncrypt), и переходите оттуда.

В остальном: счастливого отдыха!

Если вам нужен OAuth на основе Google вместо Keycloak, проверьте
Google OAuth2 с VueJS и Vert.x