Оказалось довольно легко. Я решил сохранить информацию о менеджерах в другой базе данных, а затем приложение (service-nodejs
) должно передать эту информацию в качестве претензии к Keycloak. Я проверил это на быстром запуске keycloak service-nodejs. Вот соответствующие части:
// 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 и 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;
}
}
}
Обратите внимание, что клиент service-nodejs
keycloak должен быть конфиденциальным для вызова конечной точки токена.