A 2-year old keycloak-user list question w/o an answer:
Let’s assume the system design if flexible and this fact who are the Portfolio Managers for a particular Project Manager can be either kept inside Keycloak (but not as keycloak groups) or in the client app itself. How can this be implemented as a JavaScrtipt-based authorization policy in Keycloak? I guess the request can be injected with this info somehow but can’t figure it out from the docs.
It turned out to be rather easy. I've decided to keep the info about managers in another database, and then the app (service-nodejs
) needs to pass this info as a claim to keycloak. I've tested this on the service-nodejs keycloak quickstart. Here are the relevant pieces:
// 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 "` });
});
The policy protecting the Project resource is an aggregated of OwnerOnly and 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;
}
}
}
Note that the service-nodejs
keycloak client must be confidential in order to call the token endpoint.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With