Search code examples
angularangular-routerangular9

Alternative route to disallowed guarded route?


In case of the router below, is it possible to set an alternative route (like / for instance) for when AdalGuard disallows access to route /int or to one of its children routes?

I knew I could do this inside the guard class, by calling .navigateByUrl() inside of it or returning a UrlTree. But in this case AdalGuard comes from package 'adal-angular4', so I can't do such thing.

Is there something like an 'Else' or 'Catch' pointer to another route, that I could put inside the definition of the guarded route?

Thank you very much.

app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ExtMainComponent } from './ext/ext-main/ext-main.component';
import { IntMainComponent } from './int/int-main/int-main.component';
import { EmailSenderComponent } from './int/email-sender/email-sender.component';
import { AdalGuard } from 'adal-angular4';

const routes: Routes = [
    {path: 'ext', component: ExtMainComponent},
    {
        path: 'int', component: IntMainComponent, canActivate: [AdalGuard], children: [
            {path: 'email', component: EmailSenderComponent}
        ]
    },
    {path: '**', redirectTo: '/'}
];

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


Solution

  • AdalGuard itself is simple if you look at the source code.

    You could either fork it or extend it. I would fork it so that you can retain full control over the functionality.

    As far as I can tell userInfo.authenticated always returns a synchronous boolean.

    import { Injectable } from '@angular/core';
    import { Router, UrlTree, ActivatedRouteSnapshot, CanActivate, CanActivateChild, RouterStateSnapshot } from '@angular/router';
    import { Observable } from 'rxjs';
    import { AdalService } from './adal.service';
    
    @Injectable()
    export class MyAdalGuard implements CanActivate, CanActivateChild {
    
      constructor(private adalService: AdalService,
        private router: Router
      ) { }
    
      canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ): boolean | UrlTree {
        if (this.adalService.userInfo.authenticated) {
          return true;
        }
    
        return this.router.parseUrl('/some-url');
      }
    
      public canActivateChild(
        childRoute: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ): boolean | UrlTree {
        return this.canActivate(childRoute, state);
      }
    }