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

mil*_*lan 11 javascript keycloak

一个2岁的keycloak用户列表问题没有答案:

  1. 有一个名为Project的受保护资源
  2. 和所有者 - 项目经理
  3. 每个项目经理只能访问自己的项目(仅限所有者的策略).
  4. 项目经理反过来向一个或多个投资组合经理报告.投资组合经理应该能够访问他/她的所有项目经理的项目(portforlio-manager策略).

让我们假设系统设计是灵活的,并且作为特定项目经理的投资组合经理的这个事实可以保留在Keycloak(但不是keycloak )内或客户端app本身.如何在Keycloak中将其作为基于JavaScrtipt的授权策略实现?我想这个请求可能会以某种方式注入此信息但无法从文档中找出来.

mil*_*lan 1

事实证明这相当容易。我决定将有关经理的信息保留在另一个数据库中,然后应用程序 ( service-nodejs) 需要将此信息作为对 keycloak 的声明传递。我已经在service-nodejs keycloak faststart上对此进行了测试。以下是相关部分:

// 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 "` });
  });
Run Code Online (Sandbox Code Playgroud)

保护项目资源的策略是 OwnerOnly 和 PortfolioManager 的聚合:

// 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,service-nodejskeycloak 客户端必须保密才能调用令牌端点。