workspace-ionic-app/src/app/d4sauth.service.ts

126 lines
3.3 KiB
TypeScript

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { EventType } from '@angular/router';
import { resolve } from 'dns';
import { KeycloakEventType, KeycloakService } from 'keycloak-angular';
@Injectable({
providedIn: 'root'
})
export class D4sAuthService {
redirectUrl: string = 'd4sworkspace://org.gcube.workspace/'; //'http://localhost:8100/'; //
umaUrl: string = " https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token";
audience: string = '%2Fgcube';
config: any = undefined;
uma: UmaToken | undefined;
constructor(private keycloak: KeycloakService, private httpClient: HttpClient) {
}
async login() {
if (!this.isAuthorized()) {
await this.keycloak.login({
redirectUri: this.redirectUrl,
cordovaOptions: {
hidenavigationbuttons: "yes",
toolbar:"no",
footer: "no"
}
});
}
if (!this.isAuthorized())
throw ("error authorizing");
}
isAuthorized(): boolean {
var auth = this.keycloak.getKeycloakInstance()?.authenticated;
if (!auth) return false;
else
return auth;
}
parseJwt(token: string) {
var base64Url = token.split('.')[1]
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
var jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
}).join(''))
return JSON.parse(jsonPayload);
}
async getSecureHeader(): Promise<string> {
var mustUpdate = false;
if (this.keycloak.isTokenExpired(30)) {
await this.keycloak.updateToken();
mustUpdate = true;
console.log("token refreshed");
}
if (this.uma && this.isExpired(35)){
console.log("uma expires in 35, must update")
mustUpdate = true;
}
if (mustUpdate || !this.uma)
this.uma = await this.entitlement(this.audience);
return "Bearer " + this.uma.access_token;
}
isExpired(minValidityInSeconds : number ) {
if (!this.uma) return false;
const expires: number = this.parseJwt(this.uma.access_token).exp;
const time: number = Date.now()/1000;
console.log(`exiperes in ${expires} and now is ${time}`);
return time+minValidityInSeconds > expires;
}
entitlement(resourceServerId: any): Promise<UmaToken> {
return new Promise((resolve, reject) => {
const keycloak = this.keycloak.getKeycloakInstance();
var params = "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket"
const audience = encodeURIComponent(resourceServerId)
params += "&audience=" + audience;
console.log("params " + params);
this.httpClient.post<UmaToken>(this.umaUrl, params, {
headers: {
"Content-type": "application/x-www-form-urlencoded",
"Authorization": "Bearer " + this.keycloak.getKeycloakInstance().token
}
}).subscribe(
{
error: (err) => reject("error getting uma token " + err),
next: (res: UmaToken) => resolve(res)
}
);
});
}
}
class UmaToken {
constructor(public upgraded: boolean,
public access_token: string,
public expires_in: number,
public refresh_expires_in: number,
public refresh_token: string,
public token_type: string,
public not_before_policy: number) { }
}