Role guard sometimes allows entry into secured components on localhost

时间:2018-10-22 10:13:56

标签: angular typescript authorization roles guard

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?

1 个答案:

答案 0 :(得分:0)

问题可能出在CanLoad上。 CanLoad Gaurd保护要加载的module,但是一旦加载module,则CanLoad后卫将什么也不做。

例如,假设一个用户登录了应用程序,然后他导航到某个模块。之后,他单击注销。现在,如果用户希望,由于模块已经加载,他将能够导航到相同的模块。

因此,如果您想保护自己的应用程序,则最好使用CanActivate

  

CanActivate添加到您的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;
     }

   }