Added entitlement in d4s-boot and removed keycloak-authz.js dependency

This commit is contained in:
Vincenzo Cestone 2022-04-29 18:29:30 +02:00
parent 000e790e64
commit cf2e4b4313
1 changed files with 105 additions and 22 deletions

View File

@ -20,6 +20,8 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
#locked = true
#queue = []
#interval = null
#config = null
#rpt = null
constructor() {
super()
@ -41,19 +43,18 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
console.log("Keycloak loaded")
return this.initKeycloak()
}).then((authenticated) => {
}).then(authenticated => {
if (!authenticated) {
throw "Failed to authenticate"
}
console.log("Keycloak initialized and user authenticated")
//console.log("Token exp: " + this.expirationDate(this.#keycloak.tokenParsed.exp))
//if an audience is provided then perform also authorization
if (this.#audience) {
return this.loadKeycloakAuthorization().then(() => {
this.#authorization = new KeycloakAuthorization(this.#keycloak)
console.log("Keycloak authorization loaded and initialized", this.#authorization)
})
return this.loadConfig()
} else {
return Promise.resolve()
Promise.resolve()
}
}).then(() => {
@ -90,20 +91,6 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
return this.#keycloak.init({onLoad: 'login-required', checkLoginIframe: false })
}
loadKeycloakAuthorization() {
return new Promise((resolve, reject) => {
if (typeof KeycloakAuthorization === 'undefined') {
const authz = document.createElement('script')
authz.src = this.#url + '/js/keycloak-authz.js'
authz.type = 'text/javascript'
authz.addEventListener('load', resolve)
document.head.appendChild(authz)
} else {
resolve()
}
})
}
startStateChecker() {
this.#interval = window.setInterval(() => {
if (this.#locked) {
@ -116,13 +103,15 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
if (this.#audience) {
console.log("Checking entitlement for audience", this.#audience)
const audience = encodeURIComponent(this.#audience)
return this.#authorization.entitlement(audience)
return this.entitlement(audience)
} else {
return Promise.resolve(this.#keycloak.token)
}
}).then(token => {
console.log("Authorized")
console.log("Token exp: " + this.expirationDate(this.parseJwt(token).exp))
//console.log("Datetime: " + (new Date()))
//transform all queued requests to fetches
console.log("All pending requests to promises")
let promises = this.#queue.map(r => {
@ -160,7 +149,7 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
const parseJwt = this.parseJwt
const expDt = this.expirationDate
const audience = encodeURIComponent(this.#audience)
this.#authorization.entitlement(audience).then(function (rpt) {
this.entitlement(audience).then(function (rpt) {
// onGrant callback function.
// If authorization was successful you'll receive an RPT
// with the necessary permissions to access the resource server
@ -195,6 +184,100 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
}
}
loadConfig() {
const kc = this.#keycloak
return new Promise((resolve, reject) => {
fetch(kc.authServerUrl + '/realms/' + kc.realm + '/.well-known/uma2-configuration')
.then(response => response.json())
.then(json => {
this.#config = json
resolve(true)
})
.catch(err => reject("Failed to fetch uma2-configuration from server: " + err))
})
}
/**
* Refactor of entitlement in '/js/keycloak-authz.js'
* (dependency no longer needed)
*/
entitlement(resourceServerId, authorizationRequest) {
return new Promise((resolve, reject) => {
const keycloak = this.#keycloak
const config = this.#config
if (!keycloak || !config) {
reject("Keycloak not initialized")
} else {
if (!authorizationRequest) {
authorizationRequest = {}
}
var params = "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket&client_id=" + keycloak.clientId
if (authorizationRequest.claimToken) {
params += "&claim_token=" + authorizationRequest.claimToken
if (authorizationRequest.claimTokenFormat) {
params += "&claim_token_format=" + authorizationRequest.claimTokenFormat
}
}
params += "&audience=" + resourceServerId
var permissions = authorizationRequest.permissions
if (!permissions) {
permissions = []
}
for (var i = 0; i < permissions.length; i++) {
var resource = permissions[i]
var permission = resource.id
if (resource.scopes && resource.scopes.length > 0) {
permission += "#"
for (j = 0; j < resource.scopes.length; j++) {
var scope = resource.scopes[j]
if (permission.indexOf('#') != permission.length - 1) {
permission += ","
}
permission += scope
}
}
params += "&permission=" + permission
}
var metadata = authorizationRequest.metadata
if (metadata) {
if (metadata.responseIncludeResourceName) {
params += "&response_include_resource_name=" + metadata.responseIncludeResourceName
}
if (metadata.responsePermissionsLimit) {
params += "&response_permissions_limit=" + metadata.responsePermissionsLimit
}
}
if (this.#rpt) {
params += "&rpt=" + this.#rpt
}
fetch(config.token_endpoint, {
method: 'POST',
headers: {
"Content-type" : "application/x-www-form-urlencoded",
"Authorization" : "Bearer " + this.#keycloak.token
},
body: params
})
.then(response => response.json())
.then(json => {
this.#rpt = json.access_token
resolve(this.#rpt)
})
.catch(err => reject(err))
}
})
}
static get observedAttributes() {
return ["url", "realm", "gateway", "redirect-url", "context"];
}