UNPKG

angular-auth-oidc-client

Version:

An OpenID Connect Code Flow with PKCE,Implicit Flow client for Angular

1,228 lines 155 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; import { Injectable, NgZone } from '@angular/core'; import { Router } from '@angular/router'; import { BehaviorSubject, from, Observable, of, Subject, throwError as observableThrowError, timer } from 'rxjs'; import { catchError, filter, map, race, shareReplay, switchMap, switchMapTo, take, tap } from 'rxjs/operators'; import { OidcDataService } from '../data-services/oidc-data.service'; import { AuthorizationResult } from '../models/authorization-result'; import { AuthorizationState } from '../models/authorization-state.enum'; import { ValidateStateResult } from '../models/validate-state-result.model'; import { ValidationResult } from '../models/validation-result.enum'; import { ConfigurationProvider } from './auth-configuration.provider'; import { StateValidationService } from './oidc-security-state-validation.service'; import { TokenHelperService } from './oidc-token-helper.service'; import { LoggerService } from './oidc.logger.service'; import { OidcSecurityCheckSession } from './oidc.security.check-session'; import { OidcSecurityCommon } from './oidc.security.common'; import { OidcSecuritySilentRenew } from './oidc.security.silent-renew'; import { OidcSecurityUserService } from './oidc.security.user-service'; import { OidcSecurityValidation } from './oidc.security.validation'; import { UriEncoder } from './uri-encoder'; var OidcSecurityService = /** @class */ (function () { function OidcSecurityService(oidcDataService, stateValidationService, router, oidcSecurityCheckSession, oidcSecuritySilentRenew, oidcSecurityUserService, oidcSecurityCommon, oidcSecurityValidation, tokenHelperService, loggerService, zone, httpClient, configurationProvider) { var _this = this; this.oidcDataService = oidcDataService; this.stateValidationService = stateValidationService; this.router = router; this.oidcSecurityCheckSession = oidcSecurityCheckSession; this.oidcSecuritySilentRenew = oidcSecuritySilentRenew; this.oidcSecurityUserService = oidcSecurityUserService; this.oidcSecurityCommon = oidcSecurityCommon; this.oidcSecurityValidation = oidcSecurityValidation; this.tokenHelperService = tokenHelperService; this.loggerService = loggerService; this.zone = zone; this.httpClient = httpClient; this.configurationProvider = configurationProvider; this._onModuleSetup = new Subject(); this._onCheckSessionChanged = new Subject(); this._onAuthorizationResult = new Subject(); this.checkSessionChanged = false; this.moduleSetup = false; this._isModuleSetup = new BehaviorSubject(false); this._isAuthorized = new BehaviorSubject(false); this._userData = new BehaviorSubject(''); this.authWellKnownEndpointsLoaded = false; this.runTokenValidationRunning = false; this.onModuleSetup.pipe(take(1)).subscribe((/** * @return {?} */ function () { _this.moduleSetup = true; _this._isModuleSetup.next(true); })); this._isSetupAndAuthorized = this._isModuleSetup.pipe(filter((/** * @param {?} isModuleSetup * @return {?} */ function (isModuleSetup) { return isModuleSetup; })), switchMap((/** * @return {?} */ function () { if (!_this.configurationProvider.openIDConfiguration.silent_renew) { _this.loggerService.logDebug("IsAuthorizedRace: Silent Renew Not Active. Emitting."); return from([true]); } /** @type {?} */ var race$ = _this._isAuthorized.asObservable().pipe(filter((/** * @param {?} isAuthorized * @return {?} */ function (isAuthorized) { return isAuthorized; })), take(1), tap((/** * @return {?} */ function () { return _this.loggerService.logDebug('IsAuthorizedRace: Existing token is still authorized.'); })), race(_this._onAuthorizationResult.pipe(take(1), tap((/** * @return {?} */ function () { return _this.loggerService.logDebug('IsAuthorizedRace: Silent Renew Refresh Session Complete'); })), map((/** * @return {?} */ function () { return true; }))), timer(5000).pipe( // backup, if nothing happens after 5 seconds stop waiting and emit tap((/** * @return {?} */ function () { _this.resetAuthorizationData(false); _this.oidcSecurityCommon.authNonce = ''; _this.loggerService.logWarning('IsAuthorizedRace: Timeout reached. Emitting.'); })), map((/** * @return {?} */ function () { return true; }))))); _this.loggerService.logDebug('Silent Renew is active, check if token in storage is active'); if (_this.oidcSecurityCommon.authNonce === '' || _this.oidcSecurityCommon.authNonce === undefined) { // login not running, or a second silent renew, user must login first before this will work. _this.loggerService.logDebug('Silent Renew or login not running, try to refresh the session'); _this.refreshSession(); } return race$; })), tap((/** * @return {?} */ function () { return _this.loggerService.logDebug('IsAuthorizedRace: Completed'); })), switchMapTo(this._isAuthorized.asObservable()), tap((/** * @param {?} isAuthorized * @return {?} */ function (isAuthorized) { return _this.loggerService.logDebug("getIsAuthorized: " + isAuthorized); })), shareReplay(1)); this._isSetupAndAuthorized .pipe(filter((/** * @return {?} */ function () { return _this.configurationProvider.openIDConfiguration.start_checksession; }))) .subscribe((/** * @param {?} isSetupAndAuthorized * @return {?} */ function (isSetupAndAuthorized) { if (isSetupAndAuthorized) { _this.oidcSecurityCheckSession.startCheckingSession(_this.configurationProvider.openIDConfiguration.client_id); } else { _this.oidcSecurityCheckSession.stopCheckingSession(); } })); } Object.defineProperty(OidcSecurityService.prototype, "onModuleSetup", { get: /** * @return {?} */ function () { return this._onModuleSetup.asObservable(); }, enumerable: true, configurable: true }); Object.defineProperty(OidcSecurityService.prototype, "onAuthorizationResult", { get: /** * @return {?} */ function () { return this._onAuthorizationResult.asObservable(); }, enumerable: true, configurable: true }); Object.defineProperty(OidcSecurityService.prototype, "onCheckSessionChanged", { get: /** * @return {?} */ function () { return this._onCheckSessionChanged.asObservable(); }, enumerable: true, configurable: true }); Object.defineProperty(OidcSecurityService.prototype, "onConfigurationChange", { get: /** * @return {?} */ function () { return this.configurationProvider.onConfigurationChange; }, enumerable: true, configurable: true }); /** * @param {?} openIdConfiguration * @param {?} authWellKnownEndpoints * @return {?} */ OidcSecurityService.prototype.setupModule = /** * @param {?} openIdConfiguration * @param {?} authWellKnownEndpoints * @return {?} */ function (openIdConfiguration, authWellKnownEndpoints) { var _this = this; this.configurationProvider.setup(openIdConfiguration, authWellKnownEndpoints); this.oidcSecurityCheckSession.onCheckSessionChanged.subscribe((/** * @return {?} */ function () { _this.loggerService.logDebug('onCheckSessionChanged'); _this.checkSessionChanged = true; _this._onCheckSessionChanged.next(_this.checkSessionChanged); })); /** @type {?} */ var userData = this.oidcSecurityCommon.userData; if (userData) { this.setUserData(userData); } /** @type {?} */ var isAuthorized = this.oidcSecurityCommon.isAuthorized; if (isAuthorized) { this.loggerService.logDebug('IsAuthorized setup module'); this.loggerService.logDebug(this.oidcSecurityCommon.idToken); if (this.oidcSecurityValidation.isTokenExpired(this.oidcSecurityCommon.idToken, this.configurationProvider.openIDConfiguration.silent_renew_offset_in_seconds)) { this.loggerService.logDebug('IsAuthorized setup module; id_token isTokenExpired'); } else { this.loggerService.logDebug('IsAuthorized setup module; id_token is valid'); this.setIsAuthorized(isAuthorized); } this.runTokenValidation(); } this.loggerService.logDebug('STS server: ' + this.configurationProvider.openIDConfiguration.stsServer); this._onModuleSetup.next(); if (this.configurationProvider.openIDConfiguration.silent_renew) { this.oidcSecuritySilentRenew.initRenew(); // Support authorization via DOM events. // Deregister if OidcSecurityService.setupModule is called again by any instance. // We only ever want the latest setup service to be reacting to this event. this.boundSilentRenewEvent = this.silentRenewEventHandler.bind(this); /** @type {?} */ var instanceId_1 = Math.random(); /** @type {?} */ var boundSilentRenewInitEvent_1 = ((/** * @param {?} e * @return {?} */ function (e) { if (e.detail !== instanceId_1) { window.removeEventListener('oidc-silent-renew-message', _this.boundSilentRenewEvent); window.removeEventListener('oidc-silent-renew-init', boundSilentRenewInitEvent_1); } })).bind(this); window.addEventListener('oidc-silent-renew-init', boundSilentRenewInitEvent_1, false); window.addEventListener('oidc-silent-renew-message', this.boundSilentRenewEvent, false); window.dispatchEvent(new CustomEvent('oidc-silent-renew-init', { detail: instanceId_1, })); } }; /** * @return {?} */ OidcSecurityService.prototype.getUserData = /** * @return {?} */ function () { return this._userData.asObservable(); }; /** * @return {?} */ OidcSecurityService.prototype.getIsModuleSetup = /** * @return {?} */ function () { return this._isModuleSetup.asObservable(); }; /** * @return {?} */ OidcSecurityService.prototype.getIsAuthorized = /** * @return {?} */ function () { return this._isSetupAndAuthorized; }; /** * @return {?} */ OidcSecurityService.prototype.getToken = /** * @return {?} */ function () { if (!this._isAuthorized.getValue()) { return ''; } /** @type {?} */ var token = this.oidcSecurityCommon.getAccessToken(); return decodeURIComponent(token); }; /** * @return {?} */ OidcSecurityService.prototype.getIdToken = /** * @return {?} */ function () { if (!this._isAuthorized.getValue()) { return ''; } /** @type {?} */ var token = this.oidcSecurityCommon.getIdToken(); return decodeURIComponent(token); }; /** * @param {?=} encode * @return {?} */ OidcSecurityService.prototype.getPayloadFromIdToken = /** * @param {?=} encode * @return {?} */ function (encode) { if (encode === void 0) { encode = false; } /** @type {?} */ var token = this.getIdToken(); return this.tokenHelperService.getPayloadFromToken(token, encode); }; /** * @param {?} state * @return {?} */ OidcSecurityService.prototype.setState = /** * @param {?} state * @return {?} */ function (state) { this.oidcSecurityCommon.authStateControl = state; }; /** * @return {?} */ OidcSecurityService.prototype.getState = /** * @return {?} */ function () { return this.oidcSecurityCommon.authStateControl; }; /** * @param {?} params * @return {?} */ OidcSecurityService.prototype.setCustomRequestParameters = /** * @param {?} params * @return {?} */ function (params) { this.oidcSecurityCommon.customRequestParams = params; }; // Code Flow with PCKE or Implicit Flow // Code Flow with PCKE or Implicit Flow /** * @param {?=} urlHandler * @return {?} */ OidcSecurityService.prototype.authorize = // Code Flow with PCKE or Implicit Flow /** * @param {?=} urlHandler * @return {?} */ function (urlHandler) { if (this.configurationProvider.wellKnownEndpoints) { this.authWellKnownEndpointsLoaded = true; } if (!this.authWellKnownEndpointsLoaded) { this.loggerService.logError('Well known endpoints must be loaded before user can login!'); return; } if (!this.oidcSecurityValidation.config_validate_response_type(this.configurationProvider.openIDConfiguration.response_type)) { // invalid response_type return; } this.resetAuthorizationData(false); this.loggerService.logDebug('BEGIN Authorize Code Flow, no auth data'); /** @type {?} */ var state = this.oidcSecurityCommon.authStateControl; if (!state) { state = Date.now() + '' + Math.random() + Math.random(); this.oidcSecurityCommon.authStateControl = state; } /** @type {?} */ var nonce = 'N' + Math.random() + '' + Date.now(); this.oidcSecurityCommon.authNonce = nonce; this.loggerService.logDebug('AuthorizedController created. local state: ' + this.oidcSecurityCommon.authStateControl); /** @type {?} */ var url = ''; // Code Flow if (this.configurationProvider.openIDConfiguration.response_type === 'code') { // code_challenge with "S256" /** @type {?} */ var code_verifier = 'C' + Math.random() + '' + Date.now() + '' + Date.now() + Math.random(); /** @type {?} */ var code_challenge = this.oidcSecurityValidation.generate_code_verifier(code_verifier); this.oidcSecurityCommon.code_verifier = code_verifier; if (this.configurationProvider.wellKnownEndpoints) { url = this.createAuthorizeUrl(true, code_challenge, this.configurationProvider.openIDConfiguration.redirect_url, nonce, state, this.configurationProvider.wellKnownEndpoints.authorization_endpoint || ''); } else { this.loggerService.logError('authWellKnownEndpoints is undefined'); } } else { // Implicit Flow if (this.configurationProvider.wellKnownEndpoints) { url = this.createAuthorizeUrl(false, '', this.configurationProvider.openIDConfiguration.redirect_url, nonce, state, this.configurationProvider.wellKnownEndpoints.authorization_endpoint || ''); } else { this.loggerService.logError('authWellKnownEndpoints is undefined'); } } if (urlHandler) { urlHandler(url); } else { this.redirectTo(url); } }; // Code Flow // Code Flow /** * @param {?} urlToCheck * @return {?} */ OidcSecurityService.prototype.authorizedCallbackWithCode = // Code Flow /** * @param {?} urlToCheck * @return {?} */ function (urlToCheck) { /** @type {?} */ var urlParts = urlToCheck.split('?'); /** @type {?} */ var params = new HttpParams({ fromString: urlParts[1], }); /** @type {?} */ var code = params.get('code'); /** @type {?} */ var state = params.get('state'); /** @type {?} */ var session_state = params.get('session_state'); if (code && state) { this.requestTokensWithCode(code, state, session_state); } }; // Code Flow // Code Flow /** * @param {?} code * @param {?} state * @param {?} session_state * @return {?} */ OidcSecurityService.prototype.requestTokensWithCode = // Code Flow /** * @param {?} code * @param {?} state * @param {?} session_state * @return {?} */ function (code, state, session_state) { var _this = this; this._isModuleSetup .pipe(filter((/** * @param {?} isModuleSetup * @return {?} */ function (isModuleSetup) { return isModuleSetup; })), take(1)) .subscribe((/** * @return {?} */ function () { _this.requestTokensWithCodeProcedure(code, state, session_state); })); }; // Code Flow with PCKE // Code Flow with PCKE /** * @param {?} code * @param {?} state * @param {?} session_state * @return {?} */ OidcSecurityService.prototype.requestTokensWithCodeProcedure = // Code Flow with PCKE /** * @param {?} code * @param {?} state * @param {?} session_state * @return {?} */ function (code, state, session_state) { var _this = this; /** @type {?} */ var tokenRequestUrl = ''; if (this.configurationProvider.wellKnownEndpoints && this.configurationProvider.wellKnownEndpoints.token_endpoint) { tokenRequestUrl = "" + this.configurationProvider.wellKnownEndpoints.token_endpoint; } if (!this.oidcSecurityValidation.validateStateFromHashCallback(state, this.oidcSecurityCommon.authStateControl)) { this.loggerService.logWarning('authorizedCallback incorrect state'); // ValidationResult.StatesDoNotMatch; return; } /** @type {?} */ var headers = new HttpHeaders(); headers = headers.set('Content-Type', 'application/x-www-form-urlencoded'); /** @type {?} */ var data = "grant_type=authorization_code&client_id=" + this.configurationProvider.openIDConfiguration.client_id + ("&code_verifier=" + this.oidcSecurityCommon.code_verifier + "&code=" + code + "&redirect_uri=" + this.configurationProvider.openIDConfiguration.redirect_url); if (this.oidcSecurityCommon.silentRenewRunning === 'running') { data = "grant_type=authorization_code&client_id=" + this.configurationProvider.openIDConfiguration.client_id + ("&code_verifier=" + this.oidcSecurityCommon.code_verifier + "&code=" + code + "&redirect_uri=" + this.configurationProvider.openIDConfiguration.silent_renew_url); } this.httpClient .post(tokenRequestUrl, data, { headers: headers }) .pipe(map((/** * @param {?} response * @return {?} */ function (response) { /** @type {?} */ var obj = new Object(); obj = response; obj.state = state; obj.session_state = session_state; _this.authorizedCodeFlowCallbackProcedure(obj); })), catchError((/** * @param {?} error * @return {?} */ function (error) { _this.loggerService.logError(error); _this.loggerService.logError("OidcService code request " + _this.configurationProvider.openIDConfiguration.stsServer); return of(false); }))) .subscribe(); }; // Code Flow // Code Flow /** * @private * @param {?} result * @return {?} */ OidcSecurityService.prototype.authorizedCodeFlowCallbackProcedure = // Code Flow /** * @private * @param {?} result * @return {?} */ function (result) { /** @type {?} */ var silentRenew = this.oidcSecurityCommon.silentRenewRunning; /** @type {?} */ var isRenewProcess = silentRenew === 'running'; this.loggerService.logDebug('BEGIN authorized Code Flow Callback, no auth data'); this.resetAuthorizationData(isRenewProcess); this.authorizedCallbackProcedure(result, isRenewProcess); }; // Implicit Flow // Implicit Flow /** * @private * @param {?=} hash * @return {?} */ OidcSecurityService.prototype.authorizedImplicitFlowCallbackProcedure = // Implicit Flow /** * @private * @param {?=} hash * @return {?} */ function (hash) { /** @type {?} */ var silentRenew = this.oidcSecurityCommon.silentRenewRunning; /** @type {?} */ var isRenewProcess = silentRenew === 'running'; this.loggerService.logDebug('BEGIN authorizedCallback, no auth data'); this.resetAuthorizationData(isRenewProcess); hash = hash || window.location.hash.substr(1); /** @type {?} */ var result = hash.split('&').reduce((/** * @param {?} resultData * @param {?} item * @return {?} */ function (resultData, item) { /** @type {?} */ var parts = item.split('='); resultData[(/** @type {?} */ (parts.shift()))] = parts.join('='); return resultData; }), {}); this.authorizedCallbackProcedure(result, isRenewProcess); }; // Implicit Flow // Implicit Flow /** * @param {?=} hash * @return {?} */ OidcSecurityService.prototype.authorizedImplicitFlowCallback = // Implicit Flow /** * @param {?=} hash * @return {?} */ function (hash) { var _this = this; this._isModuleSetup .pipe(filter((/** * @param {?} isModuleSetup * @return {?} */ function (isModuleSetup) { return isModuleSetup; })), take(1)) .subscribe((/** * @return {?} */ function () { _this.authorizedImplicitFlowCallbackProcedure(hash); })); }; /** * @private * @param {?} url * @return {?} */ OidcSecurityService.prototype.redirectTo = /** * @private * @param {?} url * @return {?} */ function (url) { window.location.href = url; }; // Implicit Flow // Implicit Flow /** * @private * @param {?} result * @param {?} isRenewProcess * @return {?} */ OidcSecurityService.prototype.authorizedCallbackProcedure = // Implicit Flow /** * @private * @param {?} result * @param {?} isRenewProcess * @return {?} */ function (result, isRenewProcess) { var _this = this; this.oidcSecurityCommon.authResult = result; if (!this.configurationProvider.openIDConfiguration.history_cleanup_off && !isRenewProcess) { // reset the history to remove the tokens window.history.replaceState({}, window.document.title, window.location.origin + window.location.pathname); } else { this.loggerService.logDebug('history clean up inactive'); } if (result.error) { if (isRenewProcess) { this.loggerService.logDebug(result); } else { this.loggerService.logWarning(result); } if (((/** @type {?} */ (result.error))) === 'login_required') { this._onAuthorizationResult.next(new AuthorizationResult(AuthorizationState.unauthorized, ValidationResult.LoginRequired)); } else { this._onAuthorizationResult.next(new AuthorizationResult(AuthorizationState.unauthorized, ValidationResult.SecureTokenServerError)); } this.resetAuthorizationData(false); this.oidcSecurityCommon.authNonce = ''; if (!this.configurationProvider.openIDConfiguration.trigger_authorization_result_event && !isRenewProcess) { this.router.navigate([this.configurationProvider.openIDConfiguration.unauthorized_route]); } } else { this.loggerService.logDebug(result); this.loggerService.logDebug('authorizedCallback created, begin token validation'); this.getSigningKeys().subscribe((/** * @param {?} jwtKeys * @return {?} */ function (jwtKeys) { /** @type {?} */ var validationResult = _this.getValidatedStateResult(result, jwtKeys); if (validationResult.authResponseIsValid) { _this.setAuthorizationData(validationResult.access_token, validationResult.id_token); _this.oidcSecurityCommon.silentRenewRunning = ''; if (_this.configurationProvider.openIDConfiguration.auto_userinfo) { _this.getUserinfo(isRenewProcess, result, validationResult.id_token, validationResult.decoded_id_token).subscribe((/** * @param {?} response * @return {?} */ function (response) { if (response) { _this._onAuthorizationResult.next(new AuthorizationResult(AuthorizationState.authorized, validationResult.state)); if (!_this.configurationProvider.openIDConfiguration.trigger_authorization_result_event && !isRenewProcess) { _this.router.navigate([_this.configurationProvider.openIDConfiguration.post_login_route]); } } else { _this._onAuthorizationResult.next(new AuthorizationResult(AuthorizationState.unauthorized, validationResult.state)); if (!_this.configurationProvider.openIDConfiguration.trigger_authorization_result_event && !isRenewProcess) { _this.router.navigate([_this.configurationProvider.openIDConfiguration.unauthorized_route]); } } }), (/** * @param {?} err * @return {?} */ function (err) { /* Something went wrong while getting signing key */ _this.loggerService.logWarning('Failed to retreive user info with error: ' + JSON.stringify(err)); })); } else { if (!isRenewProcess) { // userData is set to the id_token decoded, auto get user data set to false _this.oidcSecurityUserService.setUserData(validationResult.decoded_id_token); _this.setUserData(_this.oidcSecurityUserService.getUserData()); } _this.runTokenValidation(); _this._onAuthorizationResult.next(new AuthorizationResult(AuthorizationState.authorized, validationResult.state)); if (!_this.configurationProvider.openIDConfiguration.trigger_authorization_result_event && !isRenewProcess) { _this.router.navigate([_this.configurationProvider.openIDConfiguration.post_login_route]); } } } else { // something went wrong _this.loggerService.logWarning('authorizedCallback, token(s) validation failed, resetting'); _this.loggerService.logWarning(window.location.hash); _this.resetAuthorizationData(false); _this.oidcSecurityCommon.silentRenewRunning = ''; _this._onAuthorizationResult.next(new AuthorizationResult(AuthorizationState.unauthorized, validationResult.state)); if (!_this.configurationProvider.openIDConfiguration.trigger_authorization_result_event && !isRenewProcess) { _this.router.navigate([_this.configurationProvider.openIDConfiguration.unauthorized_route]); } } }), (/** * @param {?} err * @return {?} */ function (err) { /* Something went wrong while getting signing key */ _this.loggerService.logWarning('Failed to retreive siging key with error: ' + JSON.stringify(err)); _this.oidcSecurityCommon.silentRenewRunning = ''; })); } }; /** * @param {?=} isRenewProcess * @param {?=} result * @param {?=} id_token * @param {?=} decoded_id_token * @return {?} */ OidcSecurityService.prototype.getUserinfo = /** * @param {?=} isRenewProcess * @param {?=} result * @param {?=} id_token * @param {?=} decoded_id_token * @return {?} */ function (isRenewProcess, result, id_token, decoded_id_token) { var _this = this; if (isRenewProcess === void 0) { isRenewProcess = false; } result = result ? result : this.oidcSecurityCommon.authResult; id_token = id_token ? id_token : this.oidcSecurityCommon.idToken; decoded_id_token = decoded_id_token ? decoded_id_token : this.tokenHelperService.getPayloadFromToken(id_token, false); return new Observable((/** * @param {?} observer * @return {?} */ function (observer) { // flow id_token token if (_this.configurationProvider.openIDConfiguration.response_type === 'id_token token' || _this.configurationProvider.openIDConfiguration.response_type === 'code') { if (isRenewProcess && _this._userData.value) { _this.oidcSecurityCommon.sessionState = result.session_state; observer.next(true); observer.complete(); } else { _this.oidcSecurityUserService.initUserData().subscribe((/** * @return {?} */ function () { _this.loggerService.logDebug('authorizedCallback (id_token token || code) flow'); /** @type {?} */ var userData = _this.oidcSecurityUserService.getUserData(); if (_this.oidcSecurityValidation.validate_userdata_sub_id_token(decoded_id_token.sub, userData.sub)) { _this.setUserData(userData); _this.loggerService.logDebug(_this.oidcSecurityCommon.accessToken); _this.loggerService.logDebug(_this.oidcSecurityUserService.getUserData()); _this.oidcSecurityCommon.sessionState = result.session_state; _this.runTokenValidation(); observer.next(true); } else { // something went wrong, userdata sub does not match that from id_token _this.loggerService.logWarning('authorizedCallback, User data sub does not match sub in id_token'); _this.loggerService.logDebug('authorizedCallback, token(s) validation failed, resetting'); _this.resetAuthorizationData(false); observer.next(false); } observer.complete(); })); } } else { // flow id_token _this.loggerService.logDebug('authorizedCallback id_token flow'); _this.loggerService.logDebug(_this.oidcSecurityCommon.accessToken); // userData is set to the id_token decoded. No access_token. _this.oidcSecurityUserService.setUserData(decoded_id_token); _this.setUserData(_this.oidcSecurityUserService.getUserData()); _this.oidcSecurityCommon.sessionState = result.session_state; _this.runTokenValidation(); observer.next(true); observer.complete(); } })); }; /** * @param {?=} urlHandler * @return {?} */ OidcSecurityService.prototype.logoff = /** * @param {?=} urlHandler * @return {?} */ function (urlHandler) { // /connect/endsession?id_token_hint=...&post_logout_redirect_uri=https://myapp.com this.loggerService.logDebug('BEGIN Authorize, no auth data'); if (this.configurationProvider.wellKnownEndpoints) { if (this.configurationProvider.wellKnownEndpoints.end_session_endpoint) { /** @type {?} */ var end_session_endpoint = this.configurationProvider.wellKnownEndpoints.end_session_endpoint; /** @type {?} */ var id_token_hint = this.oidcSecurityCommon.idToken; /** @type {?} */ var url = this.createEndSessionUrl(end_session_endpoint, id_token_hint); this.resetAuthorizationData(false); if (this.configurationProvider.openIDConfiguration.start_checksession && this.checkSessionChanged) { this.loggerService.logDebug('only local login cleaned up, server session has changed'); } else if (urlHandler) { urlHandler(url); } else { this.redirectTo(url); } } else { this.resetAuthorizationData(false); this.loggerService.logDebug('only local login cleaned up, no end_session_endpoint'); } } else { this.loggerService.logWarning('authWellKnownEndpoints is undefined'); } }; /** * @return {?} */ OidcSecurityService.prototype.refreshSession = /** * @return {?} */ function () { if (!this.configurationProvider.openIDConfiguration.silent_renew) { return from([false]); } this.loggerService.logDebug('BEGIN refresh session Authorize'); /** @type {?} */ var state = this.oidcSecurityCommon.authStateControl; if (state === '' || state === null) { state = Date.now() + '' + Math.random() + Math.random(); this.oidcSecurityCommon.authStateControl = state; } /** @type {?} */ var nonce = 'N' + Math.random() + '' + Date.now(); this.oidcSecurityCommon.authNonce = nonce; this.loggerService.logDebug('RefreshSession created. adding myautostate: ' + this.oidcSecurityCommon.authStateControl); /** @type {?} */ var url = ''; // Code Flow if (this.configurationProvider.openIDConfiguration.response_type === 'code') { // code_challenge with "S256" /** @type {?} */ var code_verifier = 'C' + Math.random() + '' + Date.now() + '' + Date.now() + Math.random(); /** @type {?} */ var code_challenge = this.oidcSecurityValidation.generate_code_verifier(code_verifier); this.oidcSecurityCommon.code_verifier = code_verifier; if (this.configurationProvider.wellKnownEndpoints) { url = this.createAuthorizeUrl(true, code_challenge, this.configurationProvider.openIDConfiguration.silent_renew_url, nonce, state, this.configurationProvider.wellKnownEndpoints.authorization_endpoint || '', 'none'); } else { this.loggerService.logWarning('authWellKnownEndpoints is undefined'); } } else { if (this.configurationProvider.wellKnownEndpoints) { url = this.createAuthorizeUrl(false, '', this.configurationProvider.openIDConfiguration.silent_renew_url, nonce, state, this.configurationProvider.wellKnownEndpoints.authorization_endpoint || '', 'none'); } else { this.loggerService.logWarning('authWellKnownEndpoints is undefined'); } } this.oidcSecurityCommon.silentRenewRunning = 'running'; return this.oidcSecuritySilentRenew.startRenew(url); }; /** * @param {?} error * @return {?} */ OidcSecurityService.prototype.handleError = /** * @param {?} error * @return {?} */ function (error) { this.loggerService.logError(error); if (error.status === 403 || error.status === '403') { if (this.configurationProvider.openIDConfiguration.trigger_authorization_result_event) { this._onAuthorizationResult.next(new AuthorizationResult(AuthorizationState.unauthorized, ValidationResult.NotSet)); } else { this.router.navigate([this.configurationProvider.openIDConfiguration.forbidden_route]); } } else if (error.status === 401 || error.status === '401') { /** @type {?} */ var silentRenew = this.oidcSecurityCommon.silentRenewRunning; this.resetAuthorizationData(!!silentRenew); if (this.configurationProvider.openIDConfiguration.trigger_authorization_result_event) { this._onAuthorizationResult.next(new AuthorizationResult(AuthorizationState.unauthorized, ValidationResult.NotSet)); } else { this.router.navigate([this.configurationProvider.openIDConfiguration.unauthorized_route]); } } }; /** * @return {?} */ OidcSecurityService.prototype.startCheckingSilentRenew = /** * @return {?} */ function () { this.runTokenValidation(); }; /** * @return {?} */ OidcSecurityService.prototype.stopCheckingSilentRenew = /** * @return {?} */ function () { if (this._scheduledHeartBeat) { clearTimeout(this._scheduledHeartBeat); this._scheduledHeartBeat = null; this.runTokenValidationRunning = false; } }; /** * @param {?} isRenewProcess * @return {?} */ OidcSecurityService.prototype.resetAuthorizationData = /** * @param {?} isRenewProcess * @return {?} */ function (isRenewProcess) { if (!isRenewProcess) { if (this.configurationProvider.openIDConfiguration.auto_userinfo) { // Clear user data. Fixes #97. this.setUserData(''); } this.oidcSecurityCommon.resetStorageData(isRenewProcess); this.checkSessionChanged = false; this.setIsAuthorized(false); } }; /** * @return {?} */ OidcSecurityService.prototype.getEndSessionUrl = /** * @return {?} */ function () { if (this.configurationProvider.wellKnownEndpoints) { if (this.configurationProvider.wellKnownEndpoints.end_session_endpoint) { /** @type {?} */ var end_session_endpoint = this.configurationProvider.wellKnownEndpoints.end_session_endpoint; /** @type {?} */ var id_token_hint = this.oidcSecurityCommon.idToken; return this.createEndSessionUrl(end_session_endpoint, id_token_hint); } } }; /** * @private * @param {?} result * @param {?} jwtKeys * @return {?} */ OidcSecurityService.prototype.getValidatedStateResult = /** * @private * @param {?} result * @param {?} jwtKeys * @return {?} */ function (result, jwtKeys) { if (result.error) { return new ValidateStateResult('', '', false, {}); } return this.stateValidationService.validateState(result, jwtKeys); }; /** * @private * @param {?} userData * @return {?} */ OidcSecurityService.prototype.setUserData = /** * @private * @param {?} userData * @return {?} */ function (userData) { this.oidcSecurityCommon.userData = userData; this._userData.next(userData); }; /** * @private * @param {?} isAuthorized * @return {?} */ OidcSecurityService.prototype.setIsAuthorized = /** * @private * @param {?} isAuthorized * @return {?} */ function (isAuthorized) { this._isAuthorized.next(isAuthorized); }; /** * @private * @param {?} access_token * @param {?} id_token * @return {?} */ OidcSecurityService.prototype.setAuthorizationData = /** * @private * @param {?} access_token * @param {?} id_token * @return {?} */ function (access_token, id_token) { if (this.oidcSecurityCommon.accessToken !== '') { this.oidcSecurityCommon.accessToken = ''; } this.loggerService.logDebug(access_token); this.loggerService.logDebug(id_token); this.loggerService.logDebug('storing to storage, getting the roles'); this.oidcSecurityCommon.accessToken = access_token; this.oidcSecurityCommon.idToken = id_token; this.setIsAuthorized(true); this.oidcSecurityCommon.isAuthorized = true; }; /** * @private * @param {?} isCodeFlow * @param {?} code_challenge * @param {?} redirect_url * @param {?} nonce * @param {?} state * @param {?} authorization_endpoint * @param {?=} prompt * @return {?} */ OidcSecurityService.prototype.createAuthorizeUrl = /** * @private * @param {?} isCodeFlow * @param {?} code_challenge * @param {?} redirect_url * @param {?} nonce * @param {?} state * @param {?} authorization_endpoint * @param {?=} prompt * @return {?} */ function (isCodeFlow, code_challenge, redirect_url, nonce, state, authorization_endpoint, prompt) { /** @type {?} */ var urlParts = authorization_endpoint.split('?'); /** @type {?} */ var authorizationUrl = urlParts[0]; /** @type {?} */ var params = new HttpParams({ fromString: urlParts[1], encoder: new UriEncoder(), }); params = params.set('client_id', this.configurationProvider.openIDConfiguration.client_id); params = params.append('redirect_uri', redirect_url); params = params.append('response_type', this.configurationProvider.openIDConfiguration.response_type); params = params.append('scope', this.configurationProvider.openIDConfiguration.scope); params = params.append('nonce', nonce); params = params.append('state', state); if (isCodeFlow) { params = params.append('code_challenge', code_challenge); params = params.append('code_challenge_method', 'S256'); } if (prompt) { params = params.append('prompt', prompt); } if (this.configurationProvider.openIDConfiguration.hd_param) { params = params.append('hd', this.configurationProvider.openIDConfiguration.hd_param); } /** @type {?} */ var customParams = Object.assign({}, this.oidcSecurityCommon.customRequestParams); Object.keys(customParams).forEach((/** * @param {?} key * @return {?} */ function (key) { params = params.append(key, customParams[key].toString()); })); return authorizationUrl + "?" + params; }; /** * @private * @param {?} end_session_endpoint * @param {?} id_token_hint * @return {?} */ OidcSecurityService.prototype.createEndSessionUrl = /** * @private * @param {?} end_session_endpoint * @param {?} id_token_hint * @return {?} */ function (end_session_endpoint, id_token_hint) { /** @type {?} */ var urlParts = end_session_endpoint.split('?'); /** @type {?} */ var authorizationEndsessionUrl = urlParts[0]; /** @type {?} */ var params = new HttpParams({ fromString: urlParts[1], encoder: new UriEncoder(), }); params = params.set('id_token_hint', id_token_hint); params = params.append('post_logout_redirect_uri', this.configurationProvider.openIDConfiguration.post_logout_redirect_uri); return authorizationEndsessionUrl + "?" + params; }; /** * @private * @return {?} */ OidcSecurityService.prototype.getSigningKeys = /** * @private * @return {?} */ function () { if (this.configurationProvider.wellKnownEndpoints) { this.loggerService.logDebug('jwks_uri: ' + this.configurationProvider.wellKnownEndpoints.jwks_uri); return this.oidcDataService .get(this.configurationProvider.wellKnownEndpoints.jwks_uri || '') .pipe(catchError(this.handleErrorGetSigningKeys)); } else { this.loggerService.logWarning('getSigningKeys: authWellKnownEndpoints is undefined'); } return this.oidcDataService.get('undefined').pipe(catchError(this.handleErrorGetSigningKeys)); }; /** * @private * @param {?} error * @return {?} */ OidcSecurityService.prototype.handleErrorGetSigningKeys = /** * @private * @param {?} error * @return {?} */ function (error) { /** @type {?} */ var errMsg; if (error instanceof Response) { /** @type {?} */ var body = error.json() || {}; /** @type {?} */ var err = JSON.stringify(body); errMsg = error.status + " - " + (error.statusText || '') + " " + err; } else { errMsg = error.message ? error.message : error.toString(); } console.error(errMsg); return observableThrowError(errMsg); }; /** * @private * @return {?} */ OidcSecurityService.prototype.runTokenValidation = /** * @private * @return {?} */ function () { var _this = this; if (this.runTokenValidationRunning || !this.configurationProvider.openIDConfiguration.silent_renew) { return; } this.runTokenValidationRunning = true; this.loggerService.logDebug('runTokenValidation silent-renew running'); /** * First time: delay 10 seconds to call silentRenewHeartBeatCheck * Afterwards: Run this check in a 5 second interval only AFTER the previous operation ends. * @type {?} */ var silentRenewHeartBeatCheck = (/** * @return {?} */ function () { _this.loggerService.logDebug('silentRenewHeartBeatCheck\r\n' + ("\tsilentRenewRunning: " + (_this.oidcSecurityCommon.silentRenewRunning === 'running') + "\r\n") + ("\tidToken: " + !!_this.getIdToken() + "\r\n") + ("\t_userData.value: " + !!_this._userData.value)); if (_this._userData.value && _this.oidcSecurityCommon.silentRenewRunning !== 'running' && _this.getIdToken()) { if