如何在Keycloak中实现JavaScript组成员策略

11
一则两年前的Keycloak用户列表问题至今未得到答案:
  1. 有一个受保护的资源名为项目
  2. 以及一个所有者-项目经理
  3. 每个项目经理只能访问自己的项目(仅限所有者政策)。
  4. 项目经理反过来向一个或多个投资组合经理报告。 投资组合经理应该能够访问他/她的所有项目经理的项目(投资组合经理政策)。

假设系统设计是灵活的,并且特定项目经理的投资组合经理可以在Keycloak内部(但不作为keycloak groups)或客户端应用程序本身中保留此事实。如何将其实现为Keycloak中基于JavaScript的授权策略? 我猜请求可以以某种方式注入此信息,但无法从文档中找到解决方法。

1个回答

1
结果证明这相当容易。我决定将有关管理人员的信息保存在另一个数据库中,然后应用程序(service-nodejs)需要将此信息作为声明传递给keycloak。我已在service-nodejs keycloak quickstart上进行了测试。以下是相关片段:
// app.js route:

app.get('/service/project/:id',
  keycloak.enforcer(['Project'], {
      response_mode: 'permissions', 
      claims: (request) => {
          return { "portfolio.managers": ['alice', 'bob'] } //hard-coded
      }
  }), function(req, res) {
      res.json({ message: `got project "operation "` });
  });

保护项目资源的政策是OwnerOnly和PortfolioManagers的综合体:

// portfolio-managers-policy:

var context = $evaluation.getContext();
var identity = context.getIdentity();
var userid = identity.getAttributes().getValue('preferred_username').asString(0);
var managers =  context.getAttributes().getValue('portfolio.managers')

if (!managers) {
    print('managers not provided, cannot decide!');
    $evaluation.deny();
} else {
    // check if the user is one of the portfolio managers of this project:
    for (var i = 0; i < managers.size(); i++) {
        if (managers.asString(i) == userid) {
            $evaluation.grant();
            break;
        }
    }
}

请注意,service-nodejs keycloak客户端必须机密的,才能调用令牌端点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接