keycloak-angular interceptor not sending authorization header

3.8k Views Asked by At

I'm trying to integrate keycloak-angular in my angular application. The authentication flow works well, however when I make a request to my django api I get a 403. The HTTP_AUTHORIZATION header is missing and I don't understand why. When I hardcoded a header in my http service it worked.

This is the library:

https://www.npmjs.com/package/keycloak-angular

This is my keycloak config

// utility/app.init.ts
import { KeycloakService } from 'keycloak-angular';


export function initializeKeycloak(keycloak: KeycloakService): () => Promise<boolean> {
  return () =>
    keycloak.init({
      config: {
        url: 'http://sso.portal.ca/auth',
        realm: 'kedi',
        clientId: 'account'
      },
      
      bearerPrefix: 'Bearer',
      initOptions: {
          onLoad: 'login-required', // redirects to the login page
          checkLoginIframe: true,
          checkLoginIframeInterval: 1000
      }
    });
}

This is my app module

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { CoreModule } from './@core/core.module';
import { ThemeModule } from './@theme/theme.module';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import {
  NbChatModule,
  NbDatepickerModule,
  NbDialogModule,
  NbMenuModule,
  NbSidebarModule,
  NbToastrModule,
  NbWindowModule,
} from '@nebular/theme';
import { KeycloakAngularModule, KeycloakService, KeycloakBearerInterceptor } from 'keycloak-angular';
import { initializeKeycloak} from '../app/utility/app.init'

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,
    AppRoutingModule,
    NbSidebarModule.forRoot(),
    NbMenuModule.forRoot(),
    NbDatepickerModule.forRoot(),
    NbDialogModule.forRoot(),
    NbWindowModule.forRoot(),
    NbToastrModule.forRoot(),
    CoreModule.forRoot(),
    ThemeModule.forRoot(),
    KeycloakAngularModule,
  ],
  bootstrap: [AppComponent],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initializeKeycloak,
      multi: true,
      deps: [KeycloakService]
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: KeycloakBearerInterceptor,
      multi: true
    }
  ]
})
export class AppModule {
}

And this is my api service

import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import {
  HttpClient,
  HttpHeaders,
  HttpErrorResponse,
} from '@angular/common/http';


@Injectable({
  providedIn: 'root'
})
export class PortalService {
  // change later
  apiUrl: string = 'http://api.portal.ca/public';
  constructor(private http: HttpClient) { }

  getUrl(uri: string) {
    return `${this.apiUrl}/${uri}`;
  }
  
  getPartnersTableStructure() {
    return this.http.get(this.getUrl('partner/table_config/'));
  }

  getPartners() {
    return this.http.get(this.getUrl('partner'));
  }

  getEDIDocuments() {
    return this.http.get(this.getUrl('edi_document'));
  }

  getEDIDocumentsTableStructure() {
    return this.http.get(this.getUrl('edi_document/table_config'));
  }
}

Let me know if more info is needed thanks

2

There are 2 best solutions below

0
On BEST ANSWER

I was missing the silent-check-sso.html

when I added the file it just started to work

<html>
  <body>
    <script>
      parent.postMessage(location.href, location.origin);
    </script>
  </body>
</html>
1
On

Seems you’re missing a configuration line, take a look at https://www.npmjs.com/package/keycloak-angular#httpclient-interceptor. enableBearerInterceptor: true which will add the interceptor for you.

I don’t know if you even need that line because it’s active by default.

Another issue could be that (would need some insight into the code , but this is purely on speculation) if the token was not added in module/submodules where HttpClient requests were made then it would not been adding the token in http call.