diff --git a/lib/core/src/lib/auth/authentication-interceptor/auth-bearer.interceptor.spec.ts b/lib/core/src/lib/auth/authentication-interceptor/auth-bearer.interceptor.spec.ts index e32e6d8a00..ff313486e0 100644 --- a/lib/core/src/lib/auth/authentication-interceptor/auth-bearer.interceptor.spec.ts +++ b/lib/core/src/lib/auth/authentication-interceptor/auth-bearer.interceptor.spec.ts @@ -15,10 +15,10 @@ * limitations under the License. */ -import { HttpClient, HttpHandler, HttpRequest } from '@angular/common/http'; +import { HttpClient, HttpContext, HttpHandler, HttpRequest } from '@angular/common/http'; import { TestBed } from '@angular/core/testing'; import { EMPTY, Observable, of } from 'rxjs'; -import { AuthBearerInterceptor } from './auth-bearer.interceptor'; +import { AuthBearerInterceptor, BYPASS_APP_AUTH } from './auth-bearer.interceptor'; import { AuthenticationService } from '../services/authentication.service'; import { RedirectAuthService } from '../oidc/redirect-auth.service'; @@ -105,4 +105,13 @@ describe('AuthBearerInterceptor', () => { expect(addTokenToHeaderSpy).toHaveBeenCalledTimes(mockUrls.length); }); + + it('should not add auth token when BYPASS_APP_AUTH context token is set to true, even for a non-excluded URL', () => { + const context = new HttpContext().set(BYPASS_APP_AUTH, true); + const req = new HttpRequest('GET', 'https://example.com/someotherpath', null, { context }); + + interceptor.intercept(req, mockNext); + + expect(addTokenToHeaderSpy).not.toHaveBeenCalled(); + }); }); diff --git a/lib/core/src/lib/auth/authentication-interceptor/auth-bearer.interceptor.ts b/lib/core/src/lib/auth/authentication-interceptor/auth-bearer.interceptor.ts index c35e33d086..0fa594f464 100644 --- a/lib/core/src/lib/auth/authentication-interceptor/auth-bearer.interceptor.ts +++ b/lib/core/src/lib/auth/authentication-interceptor/auth-bearer.interceptor.ts @@ -18,6 +18,7 @@ import { throwError as observableThrowError, Observable } from 'rxjs'; import { Injectable, inject } from '@angular/core'; import { + HttpContextToken, HttpHandler, HttpInterceptor, HttpRequest, @@ -31,6 +32,8 @@ import { import { catchError, mergeMap } from 'rxjs/operators'; import { AuthenticationService } from '../services/authentication.service'; +export const BYPASS_APP_AUTH = new HttpContextToken(() => false); + @Injectable() export class AuthBearerInterceptor implements HttpInterceptor { private readonly authenticationService = inject(AuthenticationService); @@ -48,6 +51,10 @@ export class AuthBearerInterceptor implements HttpInterceptor { req: HttpRequest, next: HttpHandler ): Observable | HttpUserEvent> { + if (req.context.get(BYPASS_APP_AUTH)) { + return next.handle(req).pipe(catchError((error) => observableThrowError(error))); + } + if (!this.excludedUrlsRegex) { this.loadExcludedUrlsRegex(); } diff --git a/lib/core/src/lib/auth/services/time-sync.service.spec.ts b/lib/core/src/lib/auth/services/time-sync.service.spec.ts index a2c8d6b66a..62037fb0e1 100644 --- a/lib/core/src/lib/auth/services/time-sync.service.spec.ts +++ b/lib/core/src/lib/auth/services/time-sync.service.spec.ts @@ -21,6 +21,7 @@ import { TestBed } from '@angular/core/testing'; import { AppConfigService } from '../../app-config/app-config.service'; import { TimeSyncService } from './time-sync.service'; import { firstValueFrom } from 'rxjs'; +import { BYPASS_APP_AUTH } from '../authentication-interceptor/auth-bearer.interceptor'; describe('TimeSyncService', () => { let service: TimeSyncService; @@ -127,6 +128,17 @@ describe('TimeSyncService', () => { expect(req.request.method).toBe('GET'); req.error(new ProgressEvent('')); }); + + it('should set BYPASS_APP_AUTH context token and not send Authorization header on the server time request', () => { + appConfigSpy.get.and.returnValue('http://fake-server-time-url'); + + service.checkTimeSync(60).subscribe(); + + const req = httpMock.expectOne('http://fake-server-time-url'); + expect(req.request.context.get(BYPASS_APP_AUTH)).toBeTrue(); + expect(req.request.headers.has('Authorization')).toBeFalse(); + req.flush(Date.now()); + }); }); describe('isLocalTimeOutOfSync', () => { diff --git a/lib/core/src/lib/auth/services/time-sync.service.ts b/lib/core/src/lib/auth/services/time-sync.service.ts index a806d17777..e6946c41e5 100644 --- a/lib/core/src/lib/auth/services/time-sync.service.ts +++ b/lib/core/src/lib/auth/services/time-sync.service.ts @@ -15,11 +15,12 @@ * limitations under the License. */ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpContext } from '@angular/common/http'; import { Injectable, Injector, inject } from '@angular/core'; import { AppConfigService } from '../../app-config/app-config.service'; import { from, Observable, throwError } from 'rxjs'; import { catchError, map, timeout } from 'rxjs/operators'; +import { BYPASS_APP_AUTH } from '../authentication-interceptor/auth-bearer.interceptor'; export interface TimeSync { outOfSync: boolean; @@ -85,7 +86,7 @@ export class TimeSyncService { } private getServerTime(): Observable { - return from(this._http.get(this.getServerTimeUrl())).pipe( + return from(this._http.get(this.getServerTimeUrl(), { context: new HttpContext().set(BYPASS_APP_AUTH, true) })).pipe( timeout(5000), catchError(() => throwError(() => new Error('Failed to get server time'))) );