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

luk*_*ell 5 saml single-sign-on keycloak idp

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

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

Cyr*_*lle 13

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

--编辑 2019-11-08--

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

  • 我按照说明进行操作,但身份验证并未以任何方式被阻止。它对我不起作用。 (10认同)
  • 这是行不通的,因为 Keycloak 中的授权是指使用[授权服务 API](https://www.keycloak.org/docs/latest/authorization_services/)。这是客户端应用程序必须明确支持和强制执行的内容,Keycloak 本身**不**强制执行这些策略。 (4认同)

All*_*lan 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);
 }
Run Code Online (Sandbox Code Playgroud)


Sky*_*kyr 7

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

  • 将脚本捆绑在 JAR 文件中,如此处所述,通过复制到 standalone/deployments/ 来部署它(参见手册链接)
  • 启用脚本:启动 Keycloak -Dkeycloak.profile.feature.scripts=enabled
  • 在你的领域中,创建一个新的流程。在所需的子流中复制浏览器流,并将脚本身份验证器添加为最终(必需)元素: 流配置的屏幕截图
  • 现在添加到所有应该被限制为客户端角色的客户端feature:authenticate。不承担该角色的用户将无法访问该应用程序。


小智 7

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

此解决方案的关键是客户端范围。想要授权用户的应用程序需要一个范围,如电子邮件或 uid,对吗?如果您只将它们传递给某个用户在特定组中的应用程序会怎样?

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

解决方案:

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

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

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

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

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

  • 这对我不起作用 - 不会阻止用户进行身份验证(Keycloak 19.0.2) (3认同)
  • 是否可以根据应用程序限制用户?例如,我在domain.com 上有一个应用程序,在domain.com/jenkins 上有另一个应用程序。我可以限制一组用户仅用于domain.com,一组用户仅用于domain.com/jenkins吗? (2认同)

luk*_*ell 6

我是这样解决的:

  1. 在 Keycloak 中创建一个新角色。
  2. 将此角色分配给组。
  3. 在 Kycloak 中创建一个新的身份验证脚本。配置登录时允许的角色(例如user.hasRole(realm.getRole("yourRoleName")))。
  4. 在客户端的设置中,在“身份验证流覆盖”下,选择刚刚创建的身份验证脚本。

  • @lukasell,你的导航很模糊,不清楚在哪里点击什么。你能改进一下你的评论吗? (4认同)
  • 您如何在管理控制台中添加新的自定义身份验证器脚本? (2认同)