From 492dbb4d029571a27232f04f49af0f9d515c966e Mon Sep 17 00:00:00 2001 From: "Alex.Buchatsky" Date: Tue, 2 May 2023 20:40:08 +0300 Subject: [PATCH 1/2] rfc 9207 impl --- projects/lib/src/auth.config.ts | 6 +++++ projects/lib/src/oauth-service.ts | 38 ++++++++++++++++++++++++++++++- projects/lib/src/types.ts | 1 + 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/projects/lib/src/auth.config.ts b/projects/lib/src/auth.config.ts index ed14be99..4f3110e6 100644 --- a/projects/lib/src/auth.config.ts +++ b/projects/lib/src/auth.config.ts @@ -279,6 +279,12 @@ export class AuthConfig { */ public checkOrigin? = false; + /** + * Defines whether the authorization server provides the iss parameter in the authorization response. + * Set to false if you don't fetch metadata and want to skip iss parameter validation. + */ + public authorizationResponseIssParameterSupported? = true; + constructor(json?: Partial) { if (json) { Object.assign(this, json); diff --git a/projects/lib/src/oauth-service.ts b/projects/lib/src/oauth-service.ts index b241adc5..bd14c9e9 100644 --- a/projects/lib/src/oauth-service.ts +++ b/projects/lib/src/oauth-service.ts @@ -565,6 +565,8 @@ export class OAuthService extends AuthConfig implements OnDestroy { this.jwksUri = doc.jwks_uri; this.sessionCheckIFrameUrl = doc.check_session_iframe || this.sessionCheckIFrameUrl; + this.authorizationResponseIssParameterSupported = + doc.authorization_response_iss_parameter_supported || false; this.discoveryDocumentLoaded = true; this.discoveryDocumentLoadedSubject.next(doc); @@ -1743,6 +1745,7 @@ export class OAuthService extends AuthConfig implements OnDestroy { const code = parts['code']; const state = parts['state']; + const iss = parts['iss']; const sessionState = parts['session_state']; @@ -1754,6 +1757,7 @@ export class OAuthService extends AuthConfig implements OnDestroy { .replace(/code=[^&\$]*/, '') .replace(/scope=[^&\$]*/, '') .replace(/state=[^&\$]*/, '') + .replace(/iss=[^&\$]*/, '') .replace(/session_state=[^&\$]*/, '') .replace(/^\?&/, '?') .replace(/&$/, '') @@ -1766,6 +1770,21 @@ export class OAuthService extends AuthConfig implements OnDestroy { history.replaceState(null, window.name, href); } + // if Authorization Response or Error Response + if ((code || parts['error']) && !this.skipIssuerCheck) { + if ( + (this.authorizationResponseIssParameterSupported && + iss !== this.issuer) || + (!this.authorizationResponseIssParameterSupported && iss) + ) { + const err = 'Wrong issuer: ' + iss; + this.logger.warn(err); + const event = new OAuthErrorEvent('code_error', {}, parts); + this.eventsSubject.next(event); + return Promise.reject(err); + } + } + let [nonceInState, userState] = this.parseState(state); this.state = userState; @@ -1987,6 +2006,23 @@ export class OAuthService extends AuthConfig implements OnDestroy { this.debug('parsed url', parts); const state = parts['state']; + const accessToken = parts['access_token']; + const iss = parts['iss']; + + // if Access Token Response or Error Response + if ((accessToken || parts['error']) && !this.skipIssuerCheck) { + if ( + (this.authorizationResponseIssParameterSupported && + iss !== this.issuer) || + (!this.authorizationResponseIssParameterSupported && iss) + ) { + const err = 'Wrong issuer: ' + iss; + this.logger.warn(err); + const event = new OAuthErrorEvent('token_error', {}, parts); + this.eventsSubject.next(event); + return Promise.reject(err); + } + } let [nonceInState, userState] = this.parseState(state); this.state = userState; @@ -1999,7 +2035,7 @@ export class OAuthService extends AuthConfig implements OnDestroy { return Promise.reject(err); } - const accessToken = parts['access_token']; + //const accessToken = parts['access_token']; const idToken = parts['id_token']; const sessionState = parts['session_state']; const grantedScopes = parts['scope']; diff --git a/projects/lib/src/types.ts b/projects/lib/src/types.ts index db1a984a..c16fbc8b 100644 --- a/projects/lib/src/types.ts +++ b/projects/lib/src/types.ts @@ -197,4 +197,5 @@ export interface OidcDiscoveryDoc { service_documentation: string; ui_locales_supported: string[]; revocation_endpoint: string; + authorization_response_iss_parameter_supported: boolean; } From 5c94b351c6002da744e5a4b16ee5f956ae79c517 Mon Sep 17 00:00:00 2001 From: "Alex.Buchatsky" Date: Tue, 2 May 2023 20:44:54 +0300 Subject: [PATCH 2/2] comment removed --- projects/lib/src/oauth-service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/lib/src/oauth-service.ts b/projects/lib/src/oauth-service.ts index bd14c9e9..ddf886a5 100644 --- a/projects/lib/src/oauth-service.ts +++ b/projects/lib/src/oauth-service.ts @@ -2035,7 +2035,6 @@ export class OAuthService extends AuthConfig implements OnDestroy { return Promise.reject(err); } - //const accessToken = parts['access_token']; const idToken = parts['id_token']; const sessionState = parts['session_state']; const grantedScopes = parts['scope'];