1

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

Miguel Rosales
  • 769
  • 4
  • 13
  • 29

2 Answers2

3

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>
Miguel Rosales
  • 769
  • 4
  • 13
  • 29
2

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.

s.katyan
  • 71
  • 4
  • I exactly have the situation where the token is added to requests made via services which are provided in root but it is not if they belong to any of the sub-modules. Do you know why this is and how to solve it? – Tomek Aug 10 '22 at 09:00