如何将客户端访问限制为仅在密钥斗篷中的一组用户?

时间:2019-01-22 10:11:46

标签: single-sign-on saml keycloak idp

我的awx(可兼容塔楼)网页在keycloak中有一个客户端。 我只需要一个特定keycloak组中的用户即可通过此客户端登录。

如何禁止所有其他用户(一个特定的组除外)使用此keycloak客户端?

10 个答案:

答案 0 :(得分:4)

遵循Allan的回答:尽管我在如何部署它方面有些挣扎,但他的方法正在起作用(对我来说;-))。这是我的方法:

  • Bundle script in a JAR file as documented here,通过复制到独立版本/部署/中进行部署(请参见手册链接)
  • 启用脚本:使用-Dkeycloak.profile.feature.scripts=enabled
  • 启动Keycloak
  • 在您的领域中,创建一个新流程。将浏览器流复制到所需的子流中,并将脚本身份验证器添加为最终(必需)元素: Screenshot of flow config
  • 现在向应该限制客户端角色feature:authenticate的所有客户端添加。没有该角色的用户将无法访问该应用程序。

答案 1 :(得分:2)

如果有帮助,那么这里是一个脚本,该脚本可以帮助实现任何客户端的这种行为:如果客户端包含给定角色(此处称为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);
 }

答案 2 :(得分:1)

在Keycloak管理控制台上,转到“客户端”菜单,选择您的客户端。在客户端配置页面上,设置已启用授权:在上,单击保存。应该会出现一个新的 Authorization 选项卡,转到它,然后转到下面的 Policies 选项卡,单击 Create Policy 并选择 based-based政策。假设您已经通过“网上论坛”菜单定义了网上论坛,则可以restrict access to specific groups在这里。

答案 3 :(得分:1)

已解决:1.在密钥斗篷中创建一个新角色。 2.将此角色分配给组。 3.在keycloak中创建新的身份验证脚本。配置登录时允许使用的角色(例如user.hasRole(realm.getRole(“ yourRoleName”)))。 4.在客户端设置中,在“身份验证流替代”下,选择创建的身份验证(来自步骤3)。

答案 4 :(得分:1)

答案 5 :(得分:1)

我找到了不需要脚本扩展名或流程没有任何变化的解决方案。

此解决方案的关键是客户范围。想要授权用户的应用程序需要一个范围,例如电子邮件或uid,对吗?如果仅当用户属于特定组时才将它们传递给应用程序,该怎么办?

在下面,我的客户端应用程序名称是App1。

解决方案:

  1. 转到您的客户端角色(领域->客户端->单击App1->角色)
  2. 单击“添加角色”->输入名称(例如“访问”)->单击“保存”
  3. 转到客户范围(领域->客户范围)
  4. 单击客户端应用程序所需的范围(例如“电子邮件”)
  5. 通过在下拉菜单“客户端角色”中选择客户端应用程序“ App1”,在“范围”标签中分配客户端角色“访问权限”

现在,您将无法再登录到客户端应用程序App1,因为没有将“访问”角色分配给任何用户或组。您可以尝试。

让我们创建一个新组,并为其分配角色和用户。

  1. 创建组(领域->组->单击“新建”->输入名称“ App1用户”->单击保存)
  2. 在组中,选择“角色映射”,在“客户端角色”下拉列表中选择“ App1”,然后分配角色“访问”
  3. 将用户分配给“ App1用户”(领域->用户->单击用户->组->选择“ App1用户->单击加入)

Voila,所选用户可以登录App1。

答案 6 :(得分:0)

根据文档https://www.keycloak.org/docs/6.0/server_admin/#executions,您必须激活该功能才能使用“添加执行”添加一些自定义脚本。

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

@Allan具有功能:身份验证的解决方案对我来说很好

答案 7 :(得分:0)

我尝试了艾伦(Allan)的解决方案,使用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登录页面(不显示任何错误消息),这具有欺骗性,因为用户可能会有错误的感觉,即他们未登录在

此外,如果您维护多个客户端,并且需要为每个客户端检查不同的组(或角色),则必须实施所需数量的新身份验证流程。简而言之,该解决方案有效,但是它有一些缺点。我相信一个简单的功能(例如,基于组或角色来限制访问)对于身份和访问管理系统至关重要,应该在本地得到支持!

答案 8 :(得分:0)

2021 年 - Keycloak 7.4.1.GA

我为 SAML2 解决了这个问题:

  1. 添加新的身份验证流程(只需复制现有流程)

  2. 添加执行“Group Access Observer”并设置为Required

  3. 操作 -> Group Access Observer 行上的配置

  4. 填写组名

  5. 转到您的客户端并将 Authentication flow 更改为 created now。

最好的问候

example auth flow

example of config

答案 9 :(得分:0)

使用 Keycloak >= 13.x,您可能想尝试带有条件的“允许/拒绝访问”身份验证器。您可以为组分配一个角色,并根据该角色构建条件。

如果这不够灵活,请尝试我为解决该问题而构建的 this 库。