keycloak-lambda-authorizer
Version:
85 lines • 4.12 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultResourceChecker = void 0;
class DefaultResourceChecker {
constructor(options) {
this.options = options;
}
buildUri(resourceObject) {
return Object.entries(resourceObject).map(([key, value]) => `${key}=${value}`).join('&');
}
getResource(requestContent, resourceObject) {
return __awaiter(this, void 0, void 0, function* () {
const { realm, resource } = yield this.options.keycloakJson(this.options, requestContent);
const key = `${realm}:${resource}${JSON.stringify(resourceObject)}`;
const { cache } = this.options;
let resources = yield cache.get('resource', key);
// eslint-disable-next-line no-negated-condition
if (!resources) {
const umaResponse = yield this.options.umaConfiguration
.getUma2Configuration(requestContent);
const resourceRegistrationEndpoint = `${umaResponse.resource_registration_endpoint}?${this.buildUri(resourceObject)}`;
const serviceToken = yield this.options.serviceAccount
.getServiceAccountToken(requestContent);
const res = yield this.options.restClient.fetchData(resourceRegistrationEndpoint, 'GET', {
Authorization: `Bearer ${serviceToken}`,
});
resources = JSON.parse(res);
yield cache.put('resource', key, JSON.stringify(resources));
}
else {
resources = JSON.parse(resources);
}
return resources;
});
}
matchResource(requestContent, enforcer) {
return __awaiter(this, void 0, void 0, function* () {
if (!enforcer) {
throw new Error('enforcer does not exists');
}
const permissions = enforcer.resources || [];
if (enforcer.resource) {
permissions.push(enforcer.resource);
}
let resources = [];
for (let i = 0; i < permissions.length; i++) {
const resourceJson = yield this.getResource(requestContent, permissions[i]);
resources = resources.concat(resourceJson);
}
let { payload } = requestContent.token;
if (!payload.authorization) {
const tkn = yield this.options.clientAuthorization.getRPT(requestContent, enforcer);
// eslint-disable-next-line require-atomic-updates
payload = tkn.decodedAccessToken;
}
let permission;
const resource = resources.find((resId) => {
const { authorization } = payload;
if (authorization.permissions) {
permission = authorization.permissions.find((p) => p.rsid === resId);
}
return permission;
});
let hasScope = true;
if (resource) {
hasScope = !permissions.find((p) => p.scope) ||
permissions.every((p) => permission.scopes.includes(p.scope));
}
if (!resource || !hasScope) {
throw new Error('Access is denied');
}
});
}
}
exports.DefaultResourceChecker = DefaultResourceChecker;
//# sourceMappingURL=Resource.js.map
;