引言
在写这篇文章时,我纠结了一下文件名:到底是叫 authentication 还是authorization 好?
然后我突然意识到,不知是不是创造这个词的人有意为之—— auth 这个缩写其实非常巧妙地涵盖了这两个概念。
本文记录了一些我对微服务架构中认证&鉴权实现的思考和实践经验,希望能为大家提供一些参考。
认证 vs 鉴权
在讨论微服务架构中的 auth 实现之前,我们先来明确一下 authentication(认证)和 authorization(鉴权)这两个概念的区别。
-
认证(Authentication):确认用户身份的过程。常见的方法包括用户名/密码、OAuth、JWT 等。认证的目的是确保用户是他们声称的那个人。
-
鉴权(Authorization):确定用户是否有权限访问特定资源或执行特定操作的过程。鉴权通常在认证之后进行,基于用户的角色、权限等信息来决定是否允许访问。
简而言之,认证是“你是谁?”,而鉴权是“你能做什么?”。
微服务架构中的 Auth 实现
我的架构设计中有一个专门的 auth 微服务,负责处理用户的认证和鉴权请求。用户的权限是基于角色(role-based)的,每个角色对应一组权限(permissions)。此外,还支持为特定用户分配额外的权限(extra permissions)。
在设计鉴权机制时,我起初考虑了两种实现方式:
auth的数据库中维护一张uuid-role-extra_perms的表,auth的配置文件中维护role-perms映射(因为没有动态更改角色-权限的业务需求);每次有鉴权需求时,都通过 gRPC 调用HasPermission(uuid, perm)来检查用户权限。
-
好处: 权限更新及时,不会出现某个用户被撤销角色后还有响应访问权限的问题
-
坏处: 增加了网络通信的性能开销,且会让所有其他服务依赖
auth(一旦auth宕机就全部 gg),没有体现出微服务架构低耦合的优势
- 在签发
JWT token时将用户的roles与extra_perms放在payload中,在每个微服务处进行去中心化鉴权。所有微服务通过consul共享role-perms的配置文件(因为没有动态更改角色-权限的业务需求);每次有鉴权需求时,只需在每个微服务自身处完成鉴权即可。
-
好处: 实现了其他服务与
auth的解耦,且大大减少了通信产生的性能开销 -
坏处: 会出现权限撤销后,只要
token还没过期,用户就还有访问权限的情况。而且在角色更新时,必须通知被更新的用户手动登出再重新登录,以获取新的token。