My RoleGuard looks like this:
import { CanLoad, Route } from "@angular/router";
import { AuthenticationService } from "../_services";
import { Injectable } from "@angular/core";
@Injectable({ providedIn: 'root' })
export class RoleGuard implements CanLoad {
constructor(private authService: AuthenticationService) { }
canLoad(route: Route) {
let authorities = route.data.roles;
if (this.authService.hasAnyRole(authorities)) {
return true;
}
return false;
}
}
and my methods in authService:
hasAnyRole(roles: string[]): boolean {
for (let i = 0; i <= roles.length; i++) {
if (this.hasRole(roles[i])) {
return true;
}
}
return false;
}
hasRole(role: string): boolean {
let authorities = this.getAuthority();
return authorities.findIndex(a => a === role) > -1;
}
app.routing.ts :
const appRoutes: Routes = [
{
path: 'login',
component: LoginComponent,
canActivate: [NoAuthGuard]
},
{
path: 'password',
component: PasswordComponent,
canActivate: [NoAuthGuard]
},
{
path: 'change-password',
component: ChangePasswordComponent,
canActivate: [ChangePasswordGuard]
},
{
path: 'reset-password',
component: ResetPasswordComponent,
canActivate: [ResetPasswordGuard],
resolve: {
recoverPassword: ResetPasswordGuard
}
},
{
path: '',
component: HomeComponent,
canActivate: [AuthGuard],
children: [
{
path: 'users',
loadChildren: '../app/users/users.module#UsersModule',
canLoad: [RoleGuard],
data: { roles: ['AK.W.1'] }
},
{
path: 'products',
loadChildren: '../app/products/products.module#ProductsModule',
canLoad: [RoleGuard],
data: { roles: ['AK.W.1', 'AK.W.2'] }
},
{
path: 'codes',
loadChildren: '../app/codes/codes.module#CodesModule',
canLoad: [RoleGuard],
data: { roles: ['AK.W.1', 'AK.W.2'] }
},
{
path: 'reports',
loadChildren: '../app/reports/reports.module#ReportsModule',
canLoad: [RoleGuard],
data: { roles: ['AK.W.1','AK.W.2','AK.W.3'] }
}
]
},
{ path: '**', redirectTo: '' }
];
User authorized roles for components are provided in path's data and checked in AuthorizationService. Methods get user's roles from token and nextable compare them with roles provided in path's data. The problem is guard doesn't work properly. Sometimes it allows unauthorized users to let in secured components on localhost mostly after first login when app is served. Could you indicate me what's wrong with my guard?
The issue could be with CanLoad
. CanLoad
Gaurd protects a module
to be loaded but once module
is loaded then CanLoad
guard does nothing.
For example, lets say A user logged in application and he navigates to some Module. After that he click on logout. Now if user wants he will be able to navigate to same module since the it was loaded already.
So if you want to protect your application, the best would be to use CanActivate
.
Add
CanActivate
into your RoleGaurd
import { CanLoad, CanActivate, Route,Router,
ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AuthenticationService } from "../_services";
import { Injectable } from "@angular/core";
@Injectable({ providedIn: 'root' })
export class RoleGuard implements CanLoad, CanActivate {
constructor(private authService: AuthenticationService,private router: Router) { }
canLoad(route: Route) {
let authorities = route.data.roles;
if (this.authService.hasAnyRole(authorities)) {
return true;
}
return false;
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let authorities = route.data.roles;
if (this.authService.hasAnyRole(authorities)) {
return true;
}
return false;
}
}