keycloak-angular icon indicating copy to clipboard operation
keycloak-angular copied to clipboard

No Bearer token included with includeBearerTokenInterceptor

Open relivvius opened this issue 11 months ago • 13 comments

- [x] bug report -> please search for issues before submitting
- [ ] feature request

Versions.

19.0.2

Repro steps.

Create a configuration that looks like:

export const appConfig: ApplicationConfig = {
  providers: [
    provideKeycloak({
      config: environmentClient.keycloak,
      initOptions: {
        onLoad: 'check-sso',
        silentCheckSsoRedirectUri: `${window.location.origin}/assets/silent-check-sso.html`
      },
      features: [
        withAutoRefreshToken({
          onInactivityTimeout: 'logout',
          sessionTimeout: 60000
        })
      ],
      providers: [
        AutoRefreshTokenService,
        UserActivityService,
        {
          provide: INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG,
          useValue: [localhostCondition] as IncludeBearerTokenCondition[] // <-- Note that multiple conditions might be added.
        },
      ]
    }),
    provideHttpClient(withInterceptors([includeBearerTokenInterceptor])),
    provideAnimations(),
    provideRouter(appRoutes),
    provideStore(),
    provideStoreDevtools({ logOnly: !isDevMode() }),
  ]
}

The log given by the failure.

There is no bearer token included in the api call

GET /api/workspace/findAll HTTP/1.1 Accept: application/json, text/plain, / Accept-Encoding: gzip, deflate, br, zstd Accept-Language: en-GB,en Connection: keep-alive DNT: 1 Host: localhost:4200 Referer: http://localhost:4200/ Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin Sec-GPC: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 sec-ch-ua: "Brave";v="131", "Chromium";v="131", "Not_A Brand";v="24" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "macOS"

Desired functionality.

The Bearer token should be included in urls starting with http://localhost:4200

relivvius avatar Jan 08 '25 15:01 relivvius

Hi @relivvius, I noticed that your localhostCondition value doesn’t seem to be present. Could you double-check if it’s defined correctly? Additionally, is the regex aligned with your intended functionality?

If you’re unsure, I recommend reviewing the example-standalone project. It includes a working implementation that might help clarify or resolve the issue. Let me know if you’d like further guidance!

mauriciovigolo avatar Jan 08 '25 21:01 mauriciovigolo

Hi @mauriciovigolo thanks for your answer!

Here is the localhostCondition that I use:

const localhostCondition = createInterceptorCondition<IncludeBearerTokenCondition>({
  urlPattern: /^http:\/\/localhost:4200\/.*$/
});

relivvius avatar Jan 09 '25 06:01 relivvius

@mauriciovigolo could it be the provideStore()? The service hitting the http server is injected into a function effect

export const loadWorkspaces = createEffect(
    (actions$ = inject(Actions), workspaceService = inject(WorkspaceService)) => {
        return actions$.pipe(
            ofType(WorkspacesActions.initWorkspaces),
            switchMap(() =>
                workspaceService.getAllWorkspaceItems().pipe(
                    map((workspaces) =>
                      WorkspacesActions.loadWorkspacesSuccess({ workspaces })),
                    catchError((error) => {
                        console.error('Error', error);
                        return of(WorkspacesActions.loadWorkspacesFailure({ error }));
                    })
                )
            )
        );
    },
    { functional: true }
);

relivvius avatar Jan 09 '25 06:01 relivvius

I am having same issue. Authentication Bearer token not added to request.

panospcm avatar Jan 10 '25 22:01 panospcm

Having the same issue.

w-barros avatar Feb 02 '25 18:02 w-barros

Seems like the urlPattern-Parsing is broken. When I use

 urlPattern: /^(.*)?$/i,

everything works just fine.

Edit: prabably a relative/absolute URL issue: Image

FloppyNotFound avatar Feb 03 '25 14:02 FloppyNotFound

I think @FloppyNotFound is right We have the same problem and everything works with the suggested pattern

RDUser-dev avatar Feb 04 '25 12:02 RDUser-dev

If I put a breakpoint at the function @FloppyNotFound highlights above, for me the url is only the path. So if I navigate to http://localhost:8080/bingo the url argument in the findMatchingCondition method is /bingo.

For my usecase this is fine, I can rewrite the regex, but is this the expected functionality ?

m3astwood avatar Feb 04 '25 14:02 m3astwood

@m3astwood that's exactly what I meant by "relative/absolute URL issue" ;) for me, the url is "graphql" instead of "http://localhost:4200/graphql" (as visible in the right block of the screenshot)

FloppyNotFound avatar Feb 04 '25 14:02 FloppyNotFound

@FloppyNotFound ah yeah my bad missed that ! 🤦‍♂️

m3astwood avatar Feb 04 '25 14:02 m3astwood

Seems like the urlPattern-Parsing is broken. When I use

 urlPattern: /^(.*)?$/i,

everything works just fine.

Edit: prabably a relative/absolute URL issue: Image

Thanks a lot @FloppyNotFound, with the mentioned urlPattern works for me also

relivvius avatar Feb 12 '25 13:02 relivvius

Hi all. I am here looking for some guidance regarding Keycloak. Currently my frontend uses Keycloak to authenticate users. Once user is logged in, the JWT token will be returned by Keycloak. I want to bind this JWT token as the Bearer Token to the Authorization Header when I am making API call, so that my backend can receive the JWT token and determine the authenticity of the API calls.

However, I followed the Keycloak documentation but I failed to bind the Bearer Token to my API calls. It only currently binds to the first API call, and the subsequent API calls do not contain the Bearer Token. You can see in the screenshots below. Only the first API call succeeds with Bearer Token attached, and my subsequent API calls fail due to the lack of Bearer Token.

Image

Image

I am using Angular v19 and Keycloak Angular v19 as well. So, KeycloakService is deprecated. Below is my code setup.

keycloak.config.ts

import {
  AutoRefreshTokenService,
  createInterceptorCondition,
  INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG,
  IncludeBearerTokenCondition,
  provideKeycloak,
  UserActivityService,
  withAutoRefreshToken,
} from 'keycloak-angular';
import { environment } from '../../../environments/environment';

const urlCondition = createInterceptorCondition<IncludeBearerTokenCondition>({
  urlPattern: /^(.*)?$/i, //change according to your backend url
});

export const provideKeycloakAngular = () =>
  provideKeycloak({
    config: environment.keycloak,
    initOptions: {
      onLoad: 'login-required',
      checkLoginIframe: false,
      pkceMethod: 'S256',
    },
    features: [
      withAutoRefreshToken({
        onInactivityTimeout: 'logout',
        sessionTimeout: 3600000,
      }),
    ],
    providers: [
      AutoRefreshTokenService,
      UserActivityService,
      {
        provide: INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG,
        useValue: [urlCondition],
      },
    ],
  });

app.config.ts

export const appConfig: ApplicationConfig = {
  providers: [
    provideKeycloakAngular(),
    provideHttpClient(
      withInterceptors([includeBearerTokenInterceptor]),
      withInterceptorsFromDi()
    ),
    {
      provide: HTTP_INTERCEPTORS,
      useClass: HttpRequestInterceptor,
      multi: true,
    },
  ]
}

I am using a custom HTTP Interceptor too. Hope to get some help here. Thanks in advance.

hyijie98 avatar May 23 '25 03:05 hyijie98

the issue is fixed. it is because i imported HttpClientModule in another feature module (i.e. prime-ng.module.ts) too. after i remove it, the problem is fixed.

hyijie98 avatar May 27 '25 02:05 hyijie98