RBAC | 使用 Authing 实现组织机构管理

借助 Authing,可以快速实现基于角色的访问控制(RBAC)。简单来说,RBAC 指的是通过用户的角色(Role)赋予其相关权限,这实现了细粒度的访问控制,并提供了一个相比直接授予单个用户权限,更简单、可控的管理方式。

而在现实生活中,组、角色往往是分层嵌套的,呈树状结构,最常见的就是组织机构,如公司、学校等等。这篇文章,我们会设想一家互联网公司 —— 「非凡科技有限公司」,看看他们是如何使用 Authing 快速完成组织机构建模的。

一、非凡科技有限公司背景介绍

该公司约 300 名员工,其公司架构大致如下:

  • 一级部门有产品部、研发部、运营部、综合管理部
  • 一级部门下面又有二级部门,如产品部中包含产品经理和设计等。

这是一个典型的树状数据结构,有且仅有一个根节点,以及多个分层的节点。一般而言,根节点就是一家公司、一个组织,其他的每个节点都对应一个部门。

这里有一点需要注意:在 Authing 中,这样的节点对应的是一个 Group,比如「非凡科技有限公司」是一个 Group,「产品部」也是一个 Group。我们要做的,是要把这些 Group 放到他在树上所属的位置。

一个 Group 可以拥有多个角色(Role),一个角色包含一个或多个权限(Permission);而一个 Group 由若干用户(User)组成,某个 Group 中的用户会继承该 Group 下的所有角色,从而具备相关权限。

了解如何管理 Group 中的 User、如何管理 Group 中的 Role、如何配置 Role 的 Permission,请见文档:角色权限管理

了解如何查询单个用户的 Group, Role, Permission 列表,请见文档:查询用户权限

如何使用 Authing 完成组织机构管理

1、梳理组织机构节点

首先,我们需要列举出该组织结构拥有的所有节点:

  • 非凡科技有限公司
  • 产品部
  • 研发部
  • 运营部
  • 综合管理部
  • 产品经理
  • 设计
  • 开发
  • 测试
  • 运维
  • 用户运营
  • 渠道运营
  • HR
  • 财务
  • 行政

这些节点在 Authing 中都是一个 Group,所以需要先创建这些 Group:

const 非凡科技有限公司 = await createGroup("非凡科技有限公司")
const 产品部 = await createGroup('产品部')
const 产品经理 = await createGroup('产品经理')
const 设计 = await createGroup('设计')
const 研发部 = await createGroup('研发部')
const 开发 = await createGroup('开发')
const 测试 = await createGroup('测试')
const 运维 = await createGroup('运维')
const 运营部 = await createGroup('运营部')
const 用户运营 = await createGroup('用户运营')
const 渠道运营 = await createGroup('渠道运营')
const 综合管理部 = await createGroup('综合管理部')
const HR = await createGroup('HR')
const 财务 = await createGroup('财务')
const 行政 = await createGroup('行政')

2、创建组织机构

接着创建组织机构(一组树状的 Group),这需要指定根节点对应的 Group:

let org = await authing.org.createOrg({
 rootGroupId: 非凡科技有限公司._id
})

3、加入产品部及其子部门节点

接着插入产品部的各级节点:

这里需要指定以下参数:

  • 组织机构 ID
  • 该节点对应的 Group ID
  • 该节点的父节点的 Group ID

如加入产品部节点时,groupId 为 Group<产品部> 的 ID,parentGroupId 为 Group<非凡科技有限公司> 的 ID。

await authing.org.addNode({
 orgId: org._id,
 groupId: 产品部._id,
 parentGroupId: 非凡科技有限公司._id
})
await authing.org.addNode({
 orgId: org._id,
 groupId: 产品经理._id,
 parentGroupId: 产品部._id
})
await authing.org.addNode({
 orgId: org._id,
 groupId: 设计._id,
 parentGroupId: 产品部._id
})

4、以此类推,加入所有节点

研发部:

// 添加研发部
await authing.org.addNode({
 orgId: org._id,
 groupId: 研发部._id,
 parentGroupId: 非凡科技有限公司._id
})
await authing.org.addNode({
 orgId: org._id,
 groupId: 开发._id,
 parentGroupId: 研发部._id
})
await authing.org.addNode({
 orgId: org._id,
 groupId: 测试._id,
 parentGroupId: 研发部._id
})
await authing.org.addNode({
 orgId: org._id,
 groupId: 运维._id,
 parentGroupId: 研发部._id
})

运营部:

await authing.org.addNode({
 orgId: org._id,
 groupId: 运营部._id,
 parentGroupId: 非凡科技有限公司._id
})
await authing.org.addNode({
 orgId: org._id,
 groupId: 用户运营._id,
 parentGroupId: 运营部._id
})
await authing.org.addNode({
 orgId: org._id,
 groupId: 渠道运营._id,
 parentGroupId: 运营部._id
})

综合管理部:

// 添加综合管理部
await authing.org.addNode({
 orgId: org._id,
 groupId: 综合管理部._id,
 parentGroupId: 非凡科技有限公司._id
})
await authing.org.addNode({
 orgId: org._id,
 groupId: HR._id,
 parentGroupId: 综合管理部._id
})
await authing.org.addNode({
 orgId: org._id,
 groupId: 财务._id,
 parentGroupId: 综合管理部._id
})
await authing.org.addNode({
 orgId: org._id,
 groupId: 行政._id,
 parentGroupId: 综合管理部._id
})

5、查看最新组织机构结构

到现在,我们的非凡科技有限公司组织机构见建模完成了,是时候获取其最新的树状结构了:

const { tree } = await authing.org.findById(org._id)

二、如何向组织机构中添加用户和配置权限

前面说过,Authing 中一个组织结构节点对应一个 Group,对此我们提供了完整的 SDK。

1、为组织机构节点配置权限

相关 SDK 见:角色权限管理

非凡科技有限公司的所有员工,都具备开具发票、使用公司邮箱的权限。与此对应,在此我们创建两个角色:Invoice Submitter 和 Corp Email User。

其中 Invoice Submitter 具备以下权限:

  • invoice:login
  • invoice:create
  • invoice:query
  • invoice:list
  • invoice:delete

Corp Email User 具备以下权限:

  • corp-email:login
  • corp-email:send
  • corp-email:receive
  • corp-email:list
  • corp-email:detail

这可以通过以下代码完成:

const InvoiceSubmitter = await createRole('Invoice Submitter')
let permissions = await createPermissionBatch(['invoice:login', 'invoice:create', 'invoice:query', 'invoice:list', 'invoice:delete'])
await authing.authz.addPermissionToRoleBatch({
 roleId: InvoiceSubmitter._id,
 permissionIdList: permissions.map(x => x._id)
})
const CorpEmailUser = await createRole('Corp Email Use')
permissions = await createPermissionBatch(['corp-email:login', 'corp-email:send', 'corp-email:receive', 'corp-email:list', 'corp-email:detail'])
await authing.authz.addPermissionToRoleBatch({
 roleId: CorpEmailUser._id,
 permissionIdList: permissions.map(x => x._id)
})

接着让 Group 非凡科技有限公司具备 Invoice Submitter 和 Corp Email User 两个角色:

await authing.authz.addRoleToGroup({
 roleId: InvoiceSubmitter._id,
 groupId: 非凡科技有限公司._id
})
await authing.authz.addRoleToGroup({
 roleId: InvoiceSubmitter._id,
 groupId: 非凡科技有限公司._id
})

现在,非凡科技有限公司这个节点将会具备 Invoice Submitter 和 Corp Email User 两个角色

2、向组织机构节点添加用户

相关 API 见:角色权限管理

某个 Group 内的用户会继承该 Group 内所有角色的权限(如果有重叠,将会取并集)。

下面我们往用户池中注册新用户,然后将其加入非凡科技有限公司 Group 中:

const user = await createUser()
await authing.authz.addUserToGroup({
 groupId: 非凡科技有限公司._id,
 userId: user._id
})

3、查询用户具备的权限

相关 API 见:查询用户权限

const { rawList: permissionList } = await authing.userPermissionList(user._id)‌

permissionList 如下:可见,此用户已经继承了 Invoice Submitter 和 Corp Email User 两个角色的所有权限:

[
  'invoice:login',
  'invoice:create',
  'invoice:query',
  'invoice:list',
  'invoice:delete',
  'corp-email:login',
  'corp-email:send',
  'corp-email:receive',
  'corp-email:list',
  'corp-email:detail',
 ]

开发者拿到用户权限列表之后,可以在业务代码层判断用户是否具备某一特定权限,如:

if "corp-email:login" not in user.permissionList:
  return "Permission Denied"

4、使用 RBAC 的优势

  • 系统性、可重复性的权限指派
  • 更方便的用户权限审计,快速定位问题
  • 快速地添加、修改角色,甚至可以调用 API 实现
  • 减少授予用户权限时发生错误的可能性
  • 引入第三方用户/新用户/未登录用户时,赋予他们预先配置好的角色,比如 guest 分组

    更多关于 RBAC 的介绍请参考实现基于角色的访问控制(RBAC)

三、总结

本文我们以「非凡科技有限公司」为例,介绍了如何将一棵组织机构树转换成一组嵌套、有层次的 Group。通过 Authing 提供的分组角色权限管理 API,可以为 Group 配置角色、指派成员,使得该 Group 中的用户继承所需的权限,从而完成组织机构建模与权限控制。

相关阅读

  1. Authing 的故事:我为什么开发 Authing?
  2. 如何在远程办公中保持高效的研发效率?
  3. 一份普通人能理解的关于 Authing 的介绍
  4. Authing 是什么以及为什么需要 Authing?
  5. 为什么身份认证值得上云?
  6. Authing @ 2019 总结
  7. Authing 开发资源最全合集

重磅:Authing 将于2020 Q1 开源,欢迎 Star 关注 https://github.com/Authing/authing

什么是 Authing?

Authing 提供专业的身份认证和授权服务。
我们为开发者和企业提供用以保证应用程序安全所需的认证模块,这让开发人员无需成为安全专家。
你可以将任意平台的应用接入到 Authing(无论是新开发的应用还是老应用都可以),同时你还可以自定义应用程序的登录方式(如:邮箱/密码、短信/验证码、扫码登录等)。
你可以根据你使用的技术,来选择我们的 SDK 或调用相关 API 来接入你的应用。当用户发起授权请求时,Authing 会帮助你认证他们的身份和返回必要的用户信息到你的应用中。

Authing 在应用交互中的位置

你可能感兴趣的:(javascript)