angular route static paths access urls directly without permission

361 Views Asked by At

I am trying to fix a bug in a web application using java 8, spring boot, Spring MVC and front end with angular cli. When the user logins the application and is created a menu considering the user profile permission with java, but the application uses angular router with static paths, so if the user rewrite the URL he can access anything even without permissions.

const routes: Routes = [
  {
      path: '',
      component: WebservicesComponent,
      children: [
        { path: 'perfis', loadChildren: './wsperfis/wsperfis.module#WsperfisModule', },
        { path: 'acessos', loadChildren: './wsacessos/wsacessos.module#WsacessosModule', },
        { path: 'novoAcesso', loadChildren: './novo-acesso/novo-acesso.module#NovoAcessoModule', },
        { path: 'servicos', loadChildren: './wsservicos/wsservicos.module#WsservicosModule' },
        { path: 'novoperfil', loadChildren: './wsnovoperfil/wsnovoperfil.module#WsnovoperfilModule' }
      ]
  }
];


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

@CrossOrigin
    @RequestMapping("/menu")
    public List<Object> menu(@RequestParam(value = "idPerfil") int idPerfil) {

        List<Menu> menus = menuService.getMenus(idPerfil);

        List<Object> menu = new ArrayList<Object>();

        Map<String, Object> mapMenu = new HashMap<String, Object>();
        Map<String, String> mapSubMenu = new HashMap<String, String>();
        List<Object> listMapSubMenu = new ArrayList<Object>();

        for (Menu menuItem : menus) {

            if (!mapMenu.containsValue(menuItem.getPaiPrompt())) {

                mapMenu = new HashMap<String, Object>();
                listMapSubMenu = new ArrayList<Object>();

                mapMenu.put(LABEL, menuItem.getPaiPrompt());
                mapMenu.put(URL, menuItem.getPaiUrl());
                mapMenu.put(ICON, menuItem.getPaiIcon());

                for (Menu submenu : menus) {

                    if (menuItem.getPaiPrompt().equals(submenu.getPaiPrompt())) {
                        mapSubMenu = new HashMap<String, String>();
                        mapSubMenu.put(LABEL, submenu.getFilhoPrompt());
                        mapSubMenu.put(URL, submenu.getFilhoUrl());
                        mapSubMenu.put(ICON, submenu.getFilhoIcon());
                        listMapSubMenu.add(mapSubMenu);
                    }

                }
                mapMenu.put(ITEMS, listMapSubMenu);
                menu.add(mapMenu);
            }

        }

        return menu;
    }
2

There are 2 best solutions below

3
On BEST ANSWER

You should add a validation on your front and backend, for example, when path changes in frontend and component is mounted it checks for session sending its path id, backend compare that versus asigned menu, all this before making any other api call.

Another solution more complex (and secure) is adding the validation on api itself, by checking menus or user profiles, this way even if user access a page he should not (its mapped in js), he won't access unauthorized apis.

2
On

I could do it using a canActiveChild validation in a Guard file, but now I am if a issue in the first time that I call it. The service that a call there stay with the status pending in the the first time that I call it, but in the next calls it works fine. Fallow the code:

constructor(private router: Router, private _cookieService: CookieService, private comumService: ComumService) {}

canActivate() {
    if (this._cookieService.get('AuthorizationToken')) {
        return true;
    }
    this.router.navigate(['login']);
    return false;
}

canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    console.log('state.url: ' + state.url);
    // tslint:disable-next-line:triple-equals
    if (state.url == '/dashboard' || this.validaAcesso(state.url)) {
        return true;
    } else {
        console.log('Entrou aqui!!!');
        window.alert('You don\'t have permission to view this page');
        this.router.navigate(['dashboard']);
        return false;
    }
}

validaAcesso(url: string) {
    this._cookieService.getAll();
    this.comumService.validaAcesso(url).subscribe((data: Boolean) => {
        console.log(data.valueOf());
        if (data.valueOf()) {
            console.log('validaAcesso return true');
            this.result = true;
        } else {
            console.log('validaAcesso return false');
            this.result = false;
        }
    });
    return this.result;
}

}