ebondu / angular2-keycloak

Angular 2 Keycloak client wrapper
19 stars 26 forks source link

Authentication data lost after Keycloak redirects back to the app #14

Open rraksi opened 7 years ago

rraksi commented 7 years ago

Hi,

I'm trying to make this module work in my starter project but I hit some walls.

After doing some debugging and googling I came to the conclusion that after Keycloak redirects back to the application, all authentication parameters from the URL (code, state) are stripped by Angular so Keycloak.parseCallback and Keycloak.processCallback functions are unable to initialize the Keycloak object properly.

I tried to put the Keycloak initialization in a module constructor (link) so it runs before Angular strips the URL but Keycloak.prototype.processInit being called asynchronously (after keycloak.json is loaded) by the time it runs, the URL is stripped.

Maybe the initialization should be done synchronously? Or am missing something?

I used the following initOptions:

{
            checkLoginIframe: false,
            responseMode: 'query',
            flow: 'standard',
}

Could someone please provide a working example?

Thank you!

ebondu commented 7 years ago

Hi, You are right, oauth params are parsed from the callback url and you have to configure the angular router properly (I used the fragment mode). Notes that after auth sucess, the keycloak module will replace your current window URL and clean your navigation history to prevent to re-login when navigating back, so that is normal the oauth parameters diappears after the page loading.

In my case, the keycloak is initialized in the ngOnInit() :

ngOnInit() {

        this.keycloakAuthz.init();

        this.keycloak.init({
            checkLoginIframe: true,
            onLoad: 'login-required',
            responseMode: "fragment"
        });

        Keycloak.authenticatedObs.subscribe(authenticated => {
            if (authenticated) {
               ...
            }
        });
}

Check your routing module configuration (useHash param) :

@NgModule({
  imports: [
    RouterModule.forRoot(LAYOUT_ROUTES, { useHash: false })
  ],
  exports: [
    RouterModule
  ]
})
RakeshLchanSarma commented 7 years ago

Hello, I am facing same kinda issue. My application reloads after it encounters keycloak.init() .

My code look like-

` ngOnInit() {
    // Configure the Keycloak
    this.keycloakAuthz.init();
    Keycloak.config = '../assets/keycloak.json';
    // Initialise the Keycloak
    this.keycloak.init({
            checkLoginIframe: true,
            onLoad: 'login-required',
            responseMode: "fragment"
    });
     Keycloak.authenticatedObs.subscribe(auth => {
      this.isAuthenticated = auth;
      this.parsedToken = Keycloak.tokenParsed;
      console.info('APP: authentication status changed...');
    });
  }`

Routing moduel-

`@NgModule({
  imports: [
    RouterModule.forRoot(routes, { useHash: false }),
    TooltipModule.forRoot()
    ],
  exports: [RouterModule],
  providers: []
})`

module.ts-

`@NgModule({
  imports: [
    TooltipModule,
    BrowserModule,
    FormsModule,
    HttpModule,
    SharedModule,
    AppRoutingModule,
    SelectModule,
    Select2Module,
    CKEditorModule,
    Ng2Bs3ModalModule,
    BrowserAnimationsModule,
    Ng2KeycloakModule.forRoot()
  ],
  declarations: [
    AppComponent
  ],
  providers: [AppConstants,SharedService,Keycloak,KeycloakAuthorization],
  bootstrap: [ AppComponent ]
})`

Virsions:

"dependencies": {
    "@angular/core": "^4.2.5",
    "@angular/compiler-cli": "^4.2.5",
    "@ebondu/angular2-keycloak": "^0.8.3",
    "@angular/http": "^4.2.5",
    "@angular/router": "^4.2.5",

......................... } Please help me out with this. Let me know if any more info is needed.

rraksi commented 7 years ago

Hi,

@ebondu, the oauth parameters disappear before page loading, at least in my app. I tracked back the problem to the asynchronous load of the keycloak.json configuration file and therefore the remaining part of the initialization process. I made it synchronous (hardcoded the configuration for now) and it works like a charm.

The initOptions I'm using now are below, and changed the routing to useHash: false. Further more as I mentioned earlier, I put the initialization in one of my module's constructor.

checkLoginIframe: true,
responseMode: 'query',
flow: 'standard',

I need further customization of the http proxy as my app requires three types of http requests and the current proxy only supports two (first and third):

ghost commented 7 years ago

@RakeshLchanSarma

Could be a little late, but I secured my application using a guard and an interceptor. Here is a gist: https://gist.github.com/jderuere/ed94520959811157dc0954cfc4aab204

In my example, I'm supporting multi-tenant using 'realm' as a part of my URL.