引言

在写这篇文章时,我纠结了一下文件名:到底是叫 authentication 还是authorization 好?

然后我突然意识到,不知是不是创造这个词的人有意为之—— auth 这个缩写其实非常巧妙地涵盖了这两个概念。

本文记录了一些我对微服务架构中认证&鉴权实现的思考和实践经验,希望能为大家提供一些参考。

认证 vs 鉴权

在讨论微服务架构中的 auth 实现之前,我们先来明确一下 authentication(认证)和 authorization(鉴权)这两个概念的区别。

  • 认证(Authentication):确认用户身份的过程。常见的方法包括用户名/密码、OAuth、JWT 等。认证的目的是确保用户是他们声称的那个人。

  • 鉴权(Authorization):确定用户是否有权限访问特定资源或执行特定操作的过程。鉴权通常在认证之后进行,基于用户的角色、权限等信息来决定是否允许访问。

简而言之,认证是“你是谁?”,而鉴权是“你能做什么?”。

微服务架构中的 Auth 实现

我的架构设计中有一个专门的 auth 微服务,负责处理用户的认证和鉴权请求。用户的权限是基于角色(role-based)的,每个角色对应一组权限(permissions)。此外,还支持为特定用户分配额外的权限(extra permissions)。

在设计鉴权机制时,我起初考虑了两种实现方式:

  1. auth 的数据库中维护一张 uuid-role-extra_perms 的表,auth 的配置文件中维护 role-perms 映射(因为没有动态更改角色-权限的业务需求);每次有鉴权需求时,都通过 gRPC 调用 HasPermission(uuid, perm) 来检查用户权限。
  • 好处: 权限更新及时,不会出现某个用户被撤销角色后还有响应访问权限的问题

  • 坏处: 增加了网络通信的性能开销,且会让所有其他服务依赖 auth(一旦 auth 宕机就全部 gg),没有体现出微服务架构低耦合的优势

  1. 在签发 JWT token 时将用户的 rolesextra_perms 放在 payload 中,在每个微服务处进行去中心化鉴权。所有微服务通过 consul 共享 role-perms 的配置文件(因为没有动态更改角色-权限的业务需求);每次有鉴权需求时,只需在每个微服务自身处完成鉴权即可。
  • 好处: 实现了其他服务与 auth 的解耦,且大大减少了通信产生的性能开销

  • 坏处: 会出现权限撤销后,只要 token 还没过期,用户就还有访问权限的情况。而且在角色更新时,必须通知被更新的用户手动登出再重新登录,以获取新的 token