Как я могу ограничить клиентский доступ только одной группе пользователей в Keycloak?

У меня есть клиент в keycloak для моей страницы awx(ansible tower). Мне нужны только пользователи из одного конкретного keycloak группа, чтобы иметь возможность войти через этого клиента.

Как я могу запретить всем этим пользователям (кроме одной определенной группы) использовать это keycloak клиент?

10 ответов

Решение

Решено: 1. Создать новую роль в Keycloak. 2. Назначьте эту роль группе. 3. Создайте новый скрипт аутентификации в keycloak. Настройте, какая роль разрешена при входе в систему (например, user.hasRole (realm.getRole ("yourRoleName"))). 4. В настройках клиента в разделе "Переопределения потока аутентификации" выберите созданную аутентификацию (из шага 3).

Я нашел решение, которое не требует расширения скриптов или каких-либо изменений в потоке.

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

В дальнейшем имя моего клиентского приложения - App1.

Решение:

  1. Перейдите к своим клиентским ролям (область -> Клиенты -> щелкните Приложение1-> Роли)
  2. Нажмите "Добавить роль" -> введите имя (например, "доступ") -> нажмите "Сохранить".
  3. Перейдите в Client Scopes (область -> Client Scopes)
  4. Щелкните область, которая требуется вашему клиентскому приложению (например, "электронная почта").
  5. Назначьте роль клиента "доступ" на вкладке "Область действия", выбрав клиентское приложение "Приложение1" в раскрывающемся списке "Роли клиента".

Теперь вы больше не сможете войти в свое клиентское приложение App1, поскольку роль "доступ" не назначена ни одному пользователю или группе. Ты можешь попробовать.

Создадим новую группу и назначим ей роль и пользователя.

  1. Создать группу (область -> Группы -> нажмите "Создать" -> введите имя "Пользователи приложения1" -> нажмите "Сохранить")
  2. В группе выберите "Сопоставление ролей", выберите "Приложение1" в раскрывающемся списке "Роли клиента" и назначьте роль "доступ".
  3. Назначьте пользователя "Пользователи приложения 1" (область -> Пользователи -> нажмите "Пользователь" -> Группы -> выберите "Пользователи приложения 1" -> нажмите "Присоединиться")

Вуаля, выбранный пользователь может войти в App1.

В консоли администратора Keycloak перейдите в меню "Клиенты" и выберите своего клиента. На странице конфигурации клиента выберите " Авторизация включена": нажмите " Сохранить". Должна появиться новая вкладка " Авторизация ", перейдите на нее, затем на вкладку " Политики " внизу нажмите " Создать политику" и выберите " Групповая политика". Там вы можете ограничить доступ к определенным группам, предполагая, что вы уже определили свои группы через меню групп.

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

AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationFlowError");

 function authenticate(context) {
    var MANDATORY_ROLE = 'feature:authenticate';
    var username = user ? user.username : "anonymous";

    var client = session.getContext().getClient();

    LOG.debug("Checking access to authentication for client '" + client.getName() + "' through mandatory role '" + MANDATORY_ROLE + "' for user '" + username + "'");

    var mandatoryRole = client.getRole(MANDATORY_ROLE);

    if (mandatoryRole === null) {
        LOG.debug("No mandatory role '" + MANDATORY_ROLE + "' for client '" + client.getName() + "'");
        return context.success();
    }

    if (user.hasRole(mandatoryRole)) {
        LOG.info("Successful authentication for user '" + username + "' with mandatory role '" + MANDATORY_ROLE + "' for client '" + client.getName() + "'");
        return context.success();
    }

    LOG.info("Denied authentication for user '" + username + "' without mandatory role '" + MANDATORY_ROLE + "' for client '" + client.getName() + "'");
    return denyAccess(context, mandatoryRole);
 }

 function denyAccess(context, mandatoryRole) {
    var formBuilder = context.form();
    var client = session.getContext().getClient();
    var description = !mandatoryRole.getAttribute('deniedMessage').isEmpty() ? mandatoryRole.getAttribute('deniedMessage') : [''];
    var form = formBuilder
        .setAttribute('clientUrl', client.getRootUrl())
        .setAttribute('clientName', client.getName())
        .setAttribute('description', description[0])
        .createForm('denied-auth.ftl');
    return context.failure(AuthenticationFlowError.INVALID_USER, form);
 }

Продолжение ответа Аллана: его подход работает (для меня;-)), хотя у меня были некоторые трудности с его развертыванием. Вот как я это сделал:

  • Объедините сценарий в файл JAR, как описано здесь, разверните его, скопировав в автономный файл /deployments/ (см. Ссылку на руководство)
  • Включить скрипты: запустите Keycloak с -Dkeycloak.profile.feature.scripts=enabled
  • В своем царстве создайте новый поток. Дублируйте поток браузера в требуемом подпотоке и добавьте аутентификатор скрипта в качестве последнего (обязательного) элемента:
  • Теперь добавьте ко всем клиентам, которым необходимо ограничить роль клиента. feature:authenticate. Пользователи, не выполняющие эту роль, не получат доступ к приложению.

Вы можете использовать это расширение для ограничения доступа к определенной группе: https://github.com/thomasdarimont/keycloak-extension-playground/tree/master/auth-require-group-extension

2021 год - Keycloak 7.4.1.GA

Я решил это так для SAML2:

  1. Добавить новый поток аутентификации (просто скопируйте существующий)

  2. Добавьте выполнение "Group Access Observer" и установите его как Required

  3. Действия -> Настроить Group Access Observer линия

  4. Заполните название группы

  5. Идите к своему клиенту и поменяйте Authentication flow создать сейчас.

Наилучшие пожелания

С Keycloak>= 13.x вы можете попробовать аутентификаторы «Разрешить / Запретить доступ» с условиями. Вы можете назначить роль группе и построить условие на основе этой роли.

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

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

AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationFlowError");

 function authenticate(context) {
    var allowed_groups = ['foo', 'bar'];
    var username = user ? user.username : "anonymous";
    var groups = user.getGroups();
    var group_array = groups.toArray();
    
    for (var i in group_array) {
        var gn = group_array[i].getName();
        if (allowed_groups.indexOf(gn) >= 0) {
            LOG.info("Access granted for user '" + username + "' for being member of LDAP group '" + gn + "'");
            return context.success();
        }    
    }

    LOG.info("Access denied for user '" + username + ". for not being member of any of the following LDAP groups: " + allowed_groups);
    context.failure(AuthenticationFlowError.IDENTITY_PROVIDER_DISABLED, context.form().setError(
        "User doesn't have the required LDAP group membership to view this page", null).createForm("error.ftl"));
    return;
 }

Стоит упомянуть два незначительных недостатка этого решения, связанных с пользовательским интерфейсом:

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

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

Согласно документу https://www.keycloak.org/docs/6.0/server_admin/, вы должны активировать эту функцию, чтобы добавить некоторые пользовательские сценарии с "добавлением выполнения".

bin/standalone.sh|bat -Dkeycloak.profile.feature.scripts=enabled

Решение @Allan с функцией: аутентификация мне нравится

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