25

keycloak我的awx(ansible 塔)网页有一个客户端。

我只需要一个特定keycloak组的用户就可以通过这个客户端登录。

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

4

10 回答 10

12

在 Keycloak 管理控制台上,转到客户端菜单,选择您的客户端。在客户端配置页面,设置Authorization Enabled: On,点击Save。应该会出现一个新的Authorization选项卡,转到它,然后到下面的Policies选项卡,单击Create Policy并选择Group-based policy。在那里,您可以限制对特定组的访问,假设您已经通过“组”菜单定义了组。

--编辑2019-11-08--

正如评论中提到的,客户端协议必须设置为openid-connect并且访问类型必须设置为机密,以使启用授权选项可见。

于 2019-01-26T01:16:33.483 回答
11

我找到了一个不需要脚本扩展或对流程进行任何更改的解决方案。

此解决方案的关键是客户端范围。想要授权用户的应用程序需要电子邮件或 uid 之类的范围,对吗?如果您只在用户属于特定组的情况下将它们传递给应用程序怎么办?

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

解决方案:

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

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

让我们创建一个新组并将角色和用户分配给它。

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

瞧,选择的用户可以登录 App1。

于 2020-11-01T20:31:43.880 回答
7

如果有帮助,这里有一个脚本可以帮助任何客户端实现此行为:如果客户端包含给定角色(此处称为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);
 }
于 2019-07-30T12:32:27.267 回答
7

艾伦回答的后续行动:他的方法正在奏效(对我来说;-)),尽管我在如何部署它时遇到了一些困难。我是这样做的:

  • 将脚本打包到 JAR 文件中,如此处所述,通过复制到 Standalone/deployments/ 来部署它(请参阅手动链接)
  • 启用脚本:启动 Keycloak-Dkeycloak.profile.feature.scripts=enabled
  • 在您的领域中,创建一个新流程。在所需的子流程中复制浏览器流程,并将脚本身份验证器添加为最终(必需)元素: 流程配置截图
  • 现在向所有应限制客户端角色的客户端添加feature:authenticate。不承担该角色的用户将无法访问该应用程序。
于 2020-04-06T07:54:59.143 回答
6

我是这样解决的:

  1. 在 Keycloak 中创建一个新角色。
  2. 将此角色分配给组。
  3. 在 Kycloak 中创建一个新的身份验证脚本。配置登录时允许的角色(例如user.hasRole(realm.getRole("yourRoleName")))。
  4. 在客户端的设置中,在“Authentication Flow Overrides”下,选择刚刚创建的身份验证脚本。
于 2019-01-27T02:11:48.563 回答
2

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

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

@Allan 具有功能的解决方案:authenticate 对我来说看起来不错

于 2019-12-20T19:58:26.823 回答
2

您可以使用此扩展来限制对特定组的访问:https ://github.com/thomasdarimont/keycloak-extension-playground/tree/master/auth-require-group-extension

于 2020-03-26T16:47:29.473 回答
1

我尝试了 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 登录页面(不显示任何错误消息),这是具有欺骗性的,因为用户可能会有错误的感觉,他们没有登录

此外,如果您维护多个客户端并且需要为每个客户端检查不同的组(或角色),那么您必须实施尽可能多的新身份验证流程,因为您需要进行许多不同的检查。简而言之,该解决方案有效,但它有一些缺点。我相信一个简单的功能,例如基于组或角色限制访问,对于身份和访问管理系统来说是必不可少的,并且应该得到原生支持!

于 2020-11-18T21:06:29.623 回答
0

2021 年 - Keycloak 7.4.1.GA

我这样解决了SAML2

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

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

  3. 操作 ->Group Access Observer在线配置

  4. 填写组名

  5. 转到您的客户并更改Authentication flow为立即创建。

最好的祝福

示例身份验证流程

配置示例

于 2021-01-13T09:52:06.560 回答
0

使用 Keycloak >= 13.x 时,您可能需要尝试带有条件的“允许/拒绝访问”身份验证器。您可以将角色分配给组并基于角色构建条件。

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

于 2021-07-01T10:32:33.983 回答