【问题标题】:How to implement ACL / role based authorization with angular 2?如何使用 Angular 2 实现基于 ACL / 角色的授权?
【发布时间】:2017-04-08 05:08:07
【问题描述】:

使用 Angular 2 实现 ACL / 基于纸张的最佳方法是什么?

简而言之,我的场景是这样的:角色是动态的,并且基于客户端可以配置的权限,也可以是动态的。

我需要阻止用户访问他无权访问的特定资源。为此,我想到了使用 Guards of the Angular 的概念。使用 CanActivate Guard,我可以根据我在每条路线中输入的信息来设置是否让用户通过。此信息将是该路由所引用的资源的名称。当我找到守卫时,我可以与他的角色进行比较,看看他的角色是否可以访问此功能以及是否允许导航。

但这样可能会陷入另外两个问题:

1 - 如何将用户重定向到他有权访问的资源?我是否必须列出路由文件并寻找与他的角色兼容的人,然后重定向到那里?

2 - 如何禁用在它可以访问的页面上看不到的组件?例如,它可以访问列表页面 X,但它无权创建新项目,因此我需要删除 Create Something 按钮。或者更确切地说,如何使用包含某些角色的特定信息但不包含它的角色的 divs 元素来做到这一点?

我想知道在 Angular 生态系统中如何最好地处理这种情况。

感谢收听。

【问题讨论】:

  • 警告:Angular 2 将所有内容都放在客户端上,因此无法“保护”Angular 中的资源(即:密钥或数据对象),您必须在数据中执行此操作资源。所以你真正看到的是隐藏/显示视觉组件和重定向,这里:[隐藏菜单项(可以扩展到按钮、数据对象等)](stackoverflow.com/questions/36041192/…)[重定向](stackoverflow.com/questions/32896407/…)。我们从数据源中提取 ACL。
  • 我不确定您是否已经找到解决问题的方法。但是我想指出,为 [隐藏菜单项] 提供的链接 @davmor 已过时,因为它使用已弃用的旧路由器。使用当前的路由器,在注入 ActivatedRoute 之前无法获取路由数据......之后您就可以访问它的数据了。

标签: angular acl role-base-authorization


【解决方案1】:

您可以尝试为此使用ngx-permissions 库。 它支持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 page

【讨论】:

    【解决方案2】:

    查看CASLVueAurelia 中有关于集成的文章,但对于 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 })
    })
    

    文档中还有一篇关于如何map abilities to different roles的文章

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-27
      • 2017-03-09
      • 1970-01-01
      • 2017-12-08
      • 2020-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多