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

126 lines
3.3 KiB
TypeScript
Raw Normal View History

2023-03-08 15:14:12 +01:00
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
2023-03-08 17:13:03 +01:00
import { EventType } from '@angular/router';
2023-03-08 15:14:12 +01:00
import { resolve } from 'dns';
2023-03-08 17:13:03 +01:00
import { KeycloakEventType, KeycloakService } from 'keycloak-angular';
2023-03-08 15:14:12 +01:00
@Injectable({
providedIn: 'root'
})
export class D4sAuthService {
2023-03-10 11:36:53 +01:00
redirectUrl: string = 'd4sworkspace://org.gcube.workspace/'; //'http://localhost:8100/'; //
2023-03-08 15:14:12 +01:00
2023-03-08 17:13:03 +01:00
umaUrl: string = " https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token";
2023-03-08 15:14:12 +01:00
audience: string = '%2Fgcube';
config: any = undefined;
2023-03-08 17:13:03 +01:00
uma: UmaToken | undefined;
2023-03-08 15:14:12 +01:00
constructor(private keycloak: KeycloakService, private httpClient: HttpClient) {
}
async login() {
if (!this.isAuthorized()) {
2023-03-08 15:24:37 +01:00
await this.keycloak.login({
2023-03-10 11:36:53 +01:00
redirectUri: this.redirectUrl,
cordovaOptions: {
hidenavigationbuttons: "yes",
toolbar:"no",
footer: "no"
}
2023-03-08 15:14:12 +01:00
});
}
if (!this.isAuthorized())
2023-03-08 17:13:03 +01:00
throw ("error authorizing");
2023-03-08 15:14:12 +01:00
}
isAuthorized(): boolean {
var auth = this.keycloak.getKeycloakInstance()?.authenticated;
if (!auth) return false;
else
return auth;
}
2023-03-08 17:13:03 +01:00
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");
}
2023-03-13 17:39:14 +01:00
if (this.uma && this.isExpired(35)){
console.log("uma expires in 35, must update")
mustUpdate = true;
}
2023-03-08 17:13:03 +01:00
if (mustUpdate || !this.uma)
this.uma = await this.entitlement(this.audience);
return "Bearer " + this.uma.access_token;
2023-03-08 15:14:12 +01:00
}
2023-03-13 17:39:14 +01:00
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;
}
2023-03-08 15:14:12 +01:00
entitlement(resourceServerId: any): Promise<UmaToken> {
return new Promise((resolve, reject) => {
const keycloak = this.keycloak.getKeycloakInstance();
2023-03-08 17:13:03 +01:00
2023-03-08 15:14:12 +01:00
var params = "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket"
2023-03-08 17:13:03 +01:00
2023-03-08 15:14:12 +01:00
const audience = encodeURIComponent(resourceServerId)
params += "&audience=" + audience;
2023-03-08 17:13:03 +01:00
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(
2023-03-08 15:14:12 +01:00
{
2023-03-08 17:13:03 +01:00
error: (err) => reject("error getting uma token " + err),
next: (res: UmaToken) => resolve(res)
}
2023-03-08 15:14:12 +01:00
);
});
}
}
2023-03-08 17:13:03 +01:00
class UmaToken {
2023-03-08 15:14:12 +01:00
2023-03-08 17:13:03 +01:00
constructor(public upgraded: boolean,
public access_token: string,
2023-03-08 15:14:12 +01:00
public expires_in: number,
public refresh_expires_in: number,
public refresh_token: string,
public token_type: string,
2023-03-08 17:13:03 +01:00
public not_before_policy: number) { }
2023-03-08 15:14:12 +01:00
}