From 3d375b8c8875952765e98489aab78309caea86fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 08:20:46 +0000 Subject: [PATCH 1/2] build(deps): bump oauth4webapi from 2.17.0 to 3.1.1 Bumps [oauth4webapi](https://github.com/panva/oauth4webapi) from 2.17.0 to 3.1.1. - [Release notes](https://github.com/panva/oauth4webapi/releases) - [Changelog](https://github.com/panva/oauth4webapi/blob/main/CHANGELOG.md) - [Commits](https://github.com/panva/oauth4webapi/compare/v2.17.0...v3.1.1) --- updated-dependencies: - dependency-name: oauth4webapi dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- packages/hawtio/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/hawtio/package.json b/packages/hawtio/package.json index abfb73ea..4d313c10 100644 --- a/packages/hawtio/package.json +++ b/packages/hawtio/package.json @@ -62,7 +62,7 @@ "jwt-decode": "^4.0.0", "keycloak-js": "^23.0.7", "monaco-editor": "^0.52.0", - "oauth4webapi": "^2.17.0", + "oauth4webapi": "^3.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-markdown": "^8.0.7", diff --git a/yarn.lock b/yarn.lock index b7383a80..14b36c4b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2052,7 +2052,7 @@ __metadata: jwt-decode: "npm:^4.0.0" keycloak-js: "npm:^23.0.7" monaco-editor: "npm:^0.52.0" - oauth4webapi: "npm:^2.17.0" + oauth4webapi: "npm:^3.1.1" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" react-markdown: "npm:^8.0.7" @@ -11673,10 +11673,10 @@ __metadata: languageName: node linkType: hard -"oauth4webapi@npm:^2.17.0": - version: 2.17.0 - resolution: "oauth4webapi@npm:2.17.0" - checksum: 10/bfe4d3c0e5ec1a67ee00889b758cabccdb45b3cfbcfb62fee5ad935f1f0d7c78432c69718b79303956f006c0a950eccc0b1f19ef85aeb0067b85d06439704dc9 +"oauth4webapi@npm:^3.1.1": + version: 3.1.1 + resolution: "oauth4webapi@npm:3.1.1" + checksum: 10/3c62ed38bb5ea14761fc5f03031819417f8dce6743068ca308cd000316f23eb24decc2cfd8c49d9da5c253be500b46fe27460b1b8fe5fe14a96cb24b4cdfc77e languageName: node linkType: hard From a215a5108fdefc2385e4670c7d200815b8bac8ed Mon Sep 17 00:00:00 2001 From: Grzegorz Grzybek Date: Thu, 24 Oct 2024 12:38:25 +0200 Subject: [PATCH 2/2] chore(deps): Upgrade to oauth4webapi v3 (fixes #1160) --- .../src/plugins/auth/oidc/oidc-service.ts | 70 +++++++++++++------ 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/packages/hawtio/src/plugins/auth/oidc/oidc-service.ts b/packages/hawtio/src/plugins/auth/oidc/oidc-service.ts index 0900fb5a..2339bb3d 100644 --- a/packages/hawtio/src/plugins/auth/oidc/oidc-service.ts +++ b/packages/hawtio/src/plugins/auth/oidc/oidc-service.ts @@ -2,13 +2,18 @@ import { ResolveUser, userService } from '@hawtiosrc/auth/user-service' import { hawtio, Logger } from '@hawtiosrc/core' import { jwtDecode } from 'jwt-decode' import * as oidc from 'oauth4webapi' -import { AuthorizationServer, Client, OAuth2Error } from 'oauth4webapi' +import { AuthorizationResponseError, AuthorizationServer, Client, ClientAuth, OAuth2Error } from 'oauth4webapi' import { fetchPath } from '@hawtiosrc/util/fetch' import { getCookie } from '@hawtiosrc/util/https' const pluginName = 'hawtio-oidc' const log = Logger.get(pluginName) +const clientAuth: ClientAuth = (_as, client, parameters, _headers) => { + parameters.set('client_id', client.client_id) + return Promise.resolve() +} + export type OidcConfig = { /** Provider type. If "null", then OIDC is not enabled */ method: 'oidc' | null @@ -95,9 +100,13 @@ export class OidcService implements IOidcService { } else { log.info('Fetching openid-configuration') const cfgUrl = new URL(cfg!.provider) - res = await oidc.discoveryRequest(cfgUrl).catch(e => { - log.error('Failed OIDC discovery request', e) - }) + res = await oidc + .discoveryRequest(cfgUrl, { + [oidc.allowInsecureRequests]: true, + }) + .catch(e => { + log.error('Failed OIDC discovery request', e) + }) if (!res || !res.ok) { return null } @@ -219,7 +228,7 @@ export class OidcService implements IOidcService { // point of no return window.location.assign(authorizationUrl) // return unresolvable promise to wait for redirect - return new Promise((resolve, reject) => { + return new Promise((_resolve, _reject) => { log.debug('Waiting for redirect') }) } @@ -231,11 +240,14 @@ export class OidcService implements IOidcService { // there are proper OAuth2/OpenID params, so we can exchange them for access_token, refresh_token and id_token const state = urlParams!.get('state') - const authResponse = oidc.validateAuthResponse(as, client, urlParams!, state!) - - if (oidc.isOAuth2Error(authResponse)) { - log.error('OpenID Authorization error', authResponse) - return null + let authResponse + try { + authResponse = oidc.validateAuthResponse(as, client, urlParams!, state!) + } catch (e) { + if (e instanceof AuthorizationResponseError) { + log.error('OpenID Authorization error', e) + return null + } } log.info('Getting localStore data, because we have params', urlParams) @@ -252,28 +264,31 @@ export class OidcService implements IOidcService { } const res = await oidc - .authorizationCodeGrantRequest(as, client, authResponse, config.redirect_uri, loginData.cv, {}) + .authorizationCodeGrantRequest(as, client, clientAuth, authResponse!, config.redirect_uri, loginData.cv, { + [oidc.allowInsecureRequests]: true, + }) .catch(e => { log.warn('Problem accessing OpenID token endpoint', e) return null }) if (!res) { + log.warn('No authorization code grant response available') return null } const tokenResponse = await oidc - .processAuthorizationCodeOpenIDResponse(as, client, res, loginData.n, oidc.skipAuthTimeCheck) + .processAuthorizationCodeResponse(as, client, res, { + expectedNonce: loginData.n, + maxAge: oidc.skipAuthTimeCheck, + }) .catch(e => { log.warn('Problem processing OpenID token response', e) + log.error('OpenID Token error', e) return null }) if (!tokenResponse) { return null } - if (oidc.isOAuth2Error(tokenResponse)) { - log.error('OpenID Token error', tokenResponse) - return null - } const access_token = tokenResponse['access_token'] const refresh_token = tokenResponse['refresh_token'] @@ -294,6 +309,10 @@ export class OidcService implements IOidcService { } const claims = oidc.getValidatedIdTokenClaims(tokenResponse) + if (!claims) { + log.warn('No ID token returned') + return null + } const user = (claims.preferred_username ?? claims.sub) as string // clear the URL bar @@ -366,13 +385,18 @@ export class OidcService implements IOidcService { } // use the original fetch - we don't want stack overflow - const options: oidc.TokenEndpointRequestOptions = { [oidc.customFetch]: this.originalFetch } - const res = await oidc.refreshTokenGrantRequest(as, client, userInfo.refresh_token, options).catch(e => { - log.error('Problem refreshing token', e) - if (failure) { - failure() - } - }) + const options: oidc.TokenEndpointRequestOptions = { + [oidc.customFetch]: this.originalFetch, + [oidc.allowInsecureRequests]: true, + } + const res = await oidc + .refreshTokenGrantRequest(as, client, clientAuth, userInfo.refresh_token, options) + .catch(e => { + log.error('Problem refreshing token', e) + if (failure) { + failure() + } + }) if (!res) { return }