如何在Angular 2中实现ACL / 基于角色的授权?

9
什么是在Angular 2中实现ACL /基于文件的最佳方法?
简而言之,我的情况是这样的:角色是动态的,基于客户端可以配置也可以是动态的权限。
我需要防止用户访问他未经授权的特定资源。为此,我想使用Angular的守卫概念。通过CanActivate守卫,我可以根据我将放在每个路由中的信息设置是否允许用户通过。这些信息将是该路由所涉及的资源的名称。当我到达守卫时,我可以将其与他的角色进行比较,查看他的角色是否有权访问此功能以及是否允许导航。
但是这会遇到两个问题:
1-如何将用户重定向到他有权限访问的资源?我必须列出路由文件并查找与他的角色兼容的人,然后重定向到那里吗?
2-如何禁用它无法查看的组件?例如,它可以访问列表页X,但无法创建新项,因此我需要删除“创建某物”按钮。或者,如何针对包含某些角色但不适用于其角色的div元素执行此操作?
我想知道最好如何在Angluar生态系统中处理这种情况。
谢谢。

注意:Angular 2将所有内容都放在客户端上,因此“保护”在Angular中的资源(例如:秘密密钥或数据对象)是不可能的,您必须在数据源处进行保护。因此,您真正需要考虑的是隐藏/显示可视化组件和重定向,这里有两个例子:隐藏菜单项(可以扩展到按钮、数据对象等)重定向。我们从数据源中提取ACL。 - davmor
我不确定您是否已经找到了解决问题的方法。但是我想指出@davmor提供的[Hiding Menu items]链接已过时,因为它使用了已弃用的旧路由器。使用当前的路由器,没有办法获取路由数据,直到注入ActivatedRoute...之后,您才能访问它的数据。 - penleychan
发现了一篇很棒的文章 https://www.sparkbit.pl/angular-2-route-guards-real-life-example/ - vikas etagi
2个回答

4
你可以尝试使用ngx-permissions库来实现此功能。它支持then、else语法、惰性加载和隔离惰性加载。将库添加到项目中即可:
@NgModule({

 imports: [
    NgxPermissionsModule.forRoot()
 ] 
 })
 export class AppModule { }

载入角色

NgxRolesService
 .addRole('ROLE_NAME', ['permissionNameA', 'permissionNameB'])

 NgxRolesService.addRole('Guest', () => {
  return this.sessionService.checkSession().toPromise();
 }); 

 NgxRolesService.addRole('Guest', () => {
     return true;
 }); 

在模板中使用

<div *ngxPermissionsOnly="['ADMIN', 'GUEST']">
  <div>You can see this text congrats</div>
</div>

保护你的防御

const appRoutes: Routes = [
 { path: 'home',
component: HomeComponent,
canActivate: [NgxPermissionsGuard],
data: {
  permissions: {
    only: ['ADMIN', 'MODERATOR'],
    except: ['GUEST']
   }
  }
 },
];

如需详细文档,请查看Wiki页面


3

请查看CASL,其中有关于在VueAurelia中集成的文章,但是对于Angular 2+,实现应该非常相似。

主要思想是您可以为每个用户定义权限。

import { AbilityBuilder } from 'casl'


// allow to read and create Todo-s for everybody and update for assignees
export default AbilityBuilder.define(can => {
  can(['read','create'], 'Todo')
  can(['update'], 'Todo', { assignee: user.id })
})

文档中还有一篇关于如何将能力映射到不同角色的文章。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接