126 lines
3.3 KiB
TypeScript
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) { }
|
|
} |