Keycloak - Multi/2FA Factor - OTP - QR Code - Пользовательский экран входа в систему - Rest API

У меня есть своя страница входа, где пользователь вводит имя пользователя / пароль. Это имя пользователя / пароль используются для входа через Keycloak Rest API.

HTTP: // локальный: 8080 / авт / царств / Demo / протокол / OpenID-соединение / маркер

input - {username,password,grant_type,client_secret,client_id}

И в ответ я получаю access token,

Теперь я хочу включить Authenticator (Google Authenticator). Я включил его из бэкэнда. Теперь, если пользователь желает войти через мое приложение, моя страница входа мне нужна, чтобы получить ниже детали.

1.) Каким-то образом мне нужно включить QR-код, который появляется на странице входа в систему keycloak после подтверждения имени пользователя / пароля, чтобы отображаться на экране входа в систему впервые при входе пользователя после ввода имени пользователя / пароля. Так что у нас есть какой-либо API, который возвращает изображение QR-кода Keycloak в ответ.

2.) При последующем входе в систему у меня будет поле OTP, поэтому нужен API REST для передачи OTP вместе с именем пользователя / паролем.

Пожалуйста, помогите с REST API, если есть ключ. Интеграция через Javascript.

Поток, аналогичный описанному в примере использования 1 здесь

Просто хочу использовать keycloak в качестве базы данных, выполняя все операции за меня, ввод будет моим экраном. Я хочу перенаправить URL-адреса при входе в систему, но должен быть развернут автономно.

2 ответа

Мне удалось реализовать это через остальной API Keycloak. Чтобы реализовать это, вам нужно самостоятельно расширить Keycloak с помощью SPI. Для этого создайте свой собственный Java-проект и расширьте org.keycloak.services.resource.RealmResourceProvider а также org.keycloak.services.resource.RealmResourceProviderFactory. Вы можете найти дополнительную информацию в официальных документах (https://www.keycloak.org/docs/latest/server_development/#_extensions), примерах github и других сообщениях о переполнении стека, как это сделать.

После того, как вы это запустите, вы можете реализовать это следующим образом:

      @GET
@Path("your-end-point-to-fetch-the-qr")
@Produces({MediaType.APPLICATION_JSON})
public YourDtoWithSecretAndQr get2FASetup(@PathParam("username") final String username) {
    final RealmModel realm = this.session.getContext().getRealm();
    final UserModel user = this.session.users().getUserByUsername(username, realm);
    final String totpSecret = HmacOTP.generateSecret(20);
    final String totpSecretQrCode = TotpUtils.qrCode(totpSecret, realm, user);
    return new YourDtoWithSecretAndQr(totpSecret, totpSecretQrCode);
}

@POST
@Path("your-end-point-to-setup-2fa")
@Consumes("application/json")
public void setup2FA(@PathParam("username") final String username, final YourDtoWithData dto) {
    final RealmModel realm = this.session.getContext().getRealm();
    final UserModel user = this.session.users().getUserByUsername(username, realm);
    final OTPCredentialModel otpCredentialModel = OTPCredentialModel.createFromPolicy(realm, dto.getSecret(), dto.getDeviceName());
    CredentialHelper.createOTPCredential(this.session, realm, user, dto.getInitialCode(), otpCredentialModel);
}

Секрет, полученный с помощью GET, должен быть отправлен обратно с помощью POST. Исходный код - это код вашего приложения 2FA (например, Google Authenticator). QR-код - это строка, которая может отображаться в img с src 'data:image/png;base64,' + qrCodeString;

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


TL; DR. Для этого
можно использовать только существующие действия Keycloak или встроить страницу управления учетными записями пользователей по адресу https://{URL-адрес сервера keycloak} / auth / realms / {realm name} / account в iframe. Боюсь, что все. На мой взгляд, в настоящее время лучше всего просто назначать действия непосредственно учетным записям или использовать электронные письма для сброса учетных данных для назначения действий; При желании оба эти действия можно выполнить через Admin API:

Отправить электронное письмо для сброса учетных данных, содержащее назначенные действия:
https://www.keycloak.org/docs-api/11.0/rest-api/index.html#_executeactionsemail

Задайте действия непосредственно в учетной записи (включите действия в часть requiredActions пользовательского JSON, который вы отправляете в теле на конечную точку):
https://www.keycloak.org/docs-api/11.0/rest-api/index .html # _updateuser


Предыстория заключается в том, что в рамках проекта, над которым я работал, мы хотели увидеть, можем ли мы иметь интегрированный способ для пользователей установить свой начальный пароль и устройство OTP, когда для них была создана новая учетная запись, поскольку метод по умолчанию отправки им электронного письма из Keycloak с использованием функции «Сброс учетных данных» имеет ограничения: а) он не предоставляет ссылку на само приложение, если вы не переопределите тему, и если у вас есть несколько экземпляров приложения для разных пользователей, вы не имеют возможности узнать, для какого экземпляра предоставить ссылку, поэтому, возможно, придется включить их список, и б) он часто не кажется истинным для приложения, даже с изменениями темы. Если вы разумны, я бы посоветовал вам остановиться и просто использовать эту функцию - см. TL;Подробности см. Выше в разделе DR.

Короче говоря, нет конечной точки API для получения QR-кода для настройки устройства OTP. Однако есть два места, где можно получить QR-код: экран настройки устройства OTP, когда вы входите в систему как пользователь, которому назначено действие «Настроить OTP», и экран управления собственной учетной записью пользователя.

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

Второй вариант более интересен, но далек от идеала. Каждый вошедший в систему пользователь имеет доступ к странице управления учетной записью, которую можно найти по адресу https://{URL-адрес сервера keycloak}/auth/realms/{realm name}/account. Эта страница позволяет вам делать такие вещи, как изменение вашего имени, пароля и т. Д., А также позволяет вам добавить устройство OTP, если у вас его еще нет, или удалить любые существующие устройства OTP, связанные с вашей учетной записью. К этой вкладке устройства OTP на странице управления учетной записью можно напрямую перейти по https://{URL-адрес сервера keycloak}/auth/realms/{realm name}/account/totp.

Как я уже упоминал, не существует API, к которому вы можете получить доступ для просмотра QR-кода, отображаемого на этой странице. Доступ к нему возможен только через GET-запрос к https://{keycloak URL-адрес сервера}/auth/realms/{realm name}/account/totp, который возвращает HTML-код для уже упомянутой страницы. Хорошо, можем ли мы программно очистить QR-код, а затем поместить его на нашу собственную страницу в нашем приложении? Эээ, нет, не совсем. Видите ли, хотя многие конечные точки API Keycloak по праву позволяют вам отправлять токен-носитель (например, токен доступа) в заголовке авторизации для доступа и конечной точки, эта страница не будет принимать токен-носитель в качестве средства аутентификации / авторизации. Вместо этого он использует файл cookie сеанса, который привязан к URL-адресу Keycloak. Этот файл cookie устанавливается, когда вы входите в свое приложение через страницу входа в Keycloak,и поэтому эта страница управления учетной записью доступна, когда вы переходите к ней, уже выполнив вход в систему, и поскольку страница управления учетной записью использует тот же сервер и доменное имя, что и исходная страница входа в Keycloak, она имеет доступ к cookie и может позволить вам in. Этот файл cookie не может быть отправлен вашим приложением, например, в ваш собственный REST API, чтобы затем программно вызвать страницу управления учетной записью и очистить QR-код, потому что ваше приложение не имеет доступа к нему по соображениям безопасности. Это может быть что-то, что вы можете где-то изменить в Keycloak, но если есть, я настоятельно рекомендую не менять это.он имеет доступ к cookie и может позволить вам войти. Этот файл cookie не может быть отправлен вашим приложением, например, в ваш собственный REST API, чтобы затем программно вызвать страницу управления учетной записью и очистить QR-код, потому что ваше приложение не имеет доступа к нему из соображений безопасности. Это может быть что-то, что вы можете где-нибудь изменить в Keycloak, но если есть, я настоятельно рекомендую не менять это.он имеет доступ к cookie и может позволить вам войти. Этот файл cookie не может быть отправлен вашим приложением, например, в ваш собственный REST API, чтобы затем программно вызвать страницу управления учетной записью и очистить QR-код, потому что ваше приложение не имеет доступа к нему из соображений безопасности. Это может быть что-то, что вы можете где-то изменить в Keycloak, но если есть, я настоятельно рекомендую не менять это.

Итак, если мы не можем очистить страницу с нашего собственного сервера, можем ли мы что-нибудь сделать во внешнем интерфейсе? Как уже упоминалось, ваше приложение не имеет доступа к cookie сеанса, но если вы сделаете запрос (например, используя fetch или axios) в своем интерфейсном JavaScript на странице управления учетной записью, тогда этот запрос отправит cookie вместе с ним. , так что это могло работать правильно? Умм, ну на самом деле вы получите сообщение об ошибке в этом сценарии из-за CORS. CORS - это Cross-Origin-Resource-Sharing, и для того, чтобы разрешить доступ к странице Keycloak, вам нужно будет открыть настройки на сервере, чтобы разрешить доступ к ней с адреса вашего веб-сайта. Я видел несколько статей, в которых рассказывается, как при желании открыть настройки CORS в Keycloak, но я бы очень нервничал по этому поводу. Я неЯ знаю достаточно о внутреннем устройстве Keycloak и о том, как он работает, чтобы прокомментировать, насколько это опасно для безопасности, но я бы, конечно, не рекомендовал это. Здесь есть некоторая информация (Keycloak angular Заголовок Access-Control-Allow-Origin отсутствует) при изменении настройки «Web Origins» клиента Keycloak вашего приложения, но это открывает ваше приложение для серьезных потенциальных злоупотреблений. Существует также ГЛАВНАЯ проблема, заключающаяся в том, что даже если вы соскребли QR-код, устройство фактически не добавляется в учетную запись пользователя (даже если оно отображается в приложении для проверки подлинности), пока вы не введете код на страницу, на которой находится QR-код. и щелкните Сохранить. Поскольку нет конечной точки API, которую можно было бы использовать для выполнения этой операции, я не думаю, что этот вариант также жизнеспособен. Я проверил, можете ли вы использовать конечную точку получения токена по адресу https://{URL-адрес сервера keycloak}/auth/realms/{realm name}/protocol/openid-connect/token, чтобы узнать, отправляете ли вы запрос с вашим логин / пароль / код otp будет как-то "прописаться"ваше устройство и завершите процесс, но хотя вы можете получить токен таким образом, и он не жалуется на код OTP, он фактически не обращает внимания на код, потому что, насколько это касается, учетная запись пользователя не У меня нет зарегистрированного устройства. Поэтому мы должны использовать форму на странице управления учетной записью, чтобы завершить этот процесс регистрации.

Итак, последний способ, возможно, сделать это ... iframe. Извините, да, это чушь, но это все, что у вас осталось. У вас может быть точка iframe на странице управления вашей учетной записью, и поскольку пользователь вошел в систему, он сможет видеть содержимое со страницы вашего приложения. Вы можете использовать относительное позиционирование, фиксированную ширину и высоту и удалить полосы прокрутки, чтобы отображать ТОЛЬКО QR-код и поля для одноразового кода, имени устройства и кнопок Сохранить / Отменить. К сожалению, это единственный вариант на данный момент, и из-за того, насколько неприятными и ненадежными могут быть в целом iframe - они определенно не кажутся родными для вашего приложения, и вам нужно переопределить тему Keycloak, чтобы получить страницу, о которой идет речь, чтобы она больше походила на ваше приложение - я 'Я рекомендую избегать этого и использовать вместо него стандартный подход с использованием действий Keycloak и Admin API.

Если вы зашли так далеко, поздравляем, вы выиграли в Stack Overflow :-)

Другие вопросы по тегам