question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

AppAuthGuard used only on some pages

See original GitHub issue

Bug Report or Feature Request (mark with an x)

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

Versions.

keycloak-angular-4.0.0 angular-6.0.8 keycloak-4.1.0

Repro steps.

I’m testing this excellent library. I have two components: DashboardComponent and ProductComponent. I would like the dashboard to be visible without login while in the product component the user needs to be logged in

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { AppAuthGuard } from './app-auth.guard';
import { DashboardComponent } from './dashboard/dashboard.component';
import { ProductComponent } from './product/product.component';

const routes: Routes = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full'},
  { path: 'dashboard', component: DashboardComponent},
  { path: 'products', component: ProductComponent, canActivate: [AppAuthGuard] },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [AppAuthGuard]
})
export class AppRoutingModule {}

If I add canActivate: [AppAuthGuard] to the ProductComponent, and I go to the dashboard it always redirect the keycloak login page.

can it be because it uses this initialization setting?

providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initializer,
      multi: true,
      deps: [KeycloakService]
    }

How can I limit only a few pages to login

The log given by the failure.

Desired functionality.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:5
  • Comments:15 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
nmcbridecommented, Nov 24, 2018

I’m not really sure why people are asking for workarounds or fixes as the library works as it should. I didn’t have any issues putting some routes behind keycloak auth and others not.

What I would guess is happening is you left “onLoad: ‘login-required’,” set in the initOptions. Which will, you guessed it, require a login as soon as keycloak is loaded. If that isn’t what you wanted, then I’d probably read the documentation for the libraries you are using as well as the documentation for any underlying libraries like the keycloak-js adapter. I’d also look at each and every option you are using that you copy-pasted especially when it comes to anything security related.

If this is not your issue, then I would suggest creating a plunker (or something similar) so it will be easier to troubleshoot your issue and help you.

2reactions
odapercommented, May 3, 2020

Hi all I encountered the same issue and I found a workarround. When you enable the ‘login-required’ in “onLoad” property of keycloack config, you will always be redirected to the login page when bootstrapping your app, so first remove ‘login-required’ to disable the automatic redirection to the login page when accessing your public page:

const keyclockConfig: KeycloakOptions = {
  config: {
    url: '/auth',
    realm: 'myRealm',
    clientId: 'myClient',
  },
  initOptions: {
    checkLoginIframe: false,
  },
  enableBearerInterceptor: true,
  bearerPrefix: 'Bearer',
  bearerExcludedUrls: ['/assets'],
};

Then, make the default landing page to your public one in the main routing file ‘app-routing.module’ without controlling its access by the AuthGuard, as follows:

const routes: Routes = [
  {
    path: 'pages',
    loadChildren: '@app/home/home.module#MainModule',
    canActivate: [AuthGuardService]
  },
  { path: '', component: MyPublicComponent }
];

The ‘keycloak-service’ calls the ‘login’ if the token is not valid (in case of public page for example), you have to disable it by providing a custom class instead of ‘KeycloakService’, so add in ‘app.module’ the following provider: { provide: KeycloakService, useClass: CustomKeycloakService }, And create the custom service by extending ‘KeycloakService’:

import { Injectable, Injector } from '@angular/core';
import { KeycloakService } from 'keycloak-angular';

@Injectable({
  providedIn: 'root'
})
export class CustomKeycloakService extends KeycloakService {
  async getToken(forceLogin = false): Promise<string> {
    try {
      await this.updateToken(10);
      return this.getKeycloakInstance().token;
    } catch (error) {
      if (forceLogin) {
        this.login();
      } else {
        throw error;
      }
    }
  }
}

Only the ‘getToken’ method is overwritten in order to change the default parameter ‘forceLogin’ to false which is true by default.

And finally, in your AuthGuard, you have to call the login check (redirection to login page will be automatically fired for no authenticated user):

isAccessAllowed(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Promise<boolean> {
    return new Promise((resolve, reject) => {
      if (!this.authenticated) {
        this.keycloakAngular.login().catch((e) => console.error(e));
        return resolve(false);
      }
      return resolve(true);
    });
  }

By this way, your public page will be accessible for public users and your internal pages are automatically secured by keycloak checks.

Note: do not inject the KeycloakService in your public page because the ‘authenticated’ status will be always false and you can’t do redirection for example if the user is authenticated, because the service is updated after calling the login which is disabled in that page and only fired for our internal pages via the Guard.

Hope this can help 😃

Thanks

Read more comments on GitHub >

github_iconTop Results From Across the Web

Authentication in Angular using Keycloak - Medium
The AppAuthGuard performs the user access validator function. That is, it helps in restricting user access to certain pages across the ...
Read more >
How to secure some routes in angular - Keycloak Discourse
I installed keycloak package for angular and it works fine, but now I have two pages that do not need to be redirect...
Read more >
"No provider for AuthGuard!" using CanActivate in Angular 2
In my header.component.ts file, when I try to access any routes, it's working just fine, but when I try to access the guarded...
Read more >
Angular - Authguards... - LinkedIn
We may be having many numbers of pages on our app, some may be used by logged in users, and some can be...
Read more >
Securing Angular Applications with Auth0 and Deploying to ...
In just a few short minutes, you can create a new Angular application, ... Using the libraries that the team at Auth0 has...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found