身份认证与访问控制
咱们直接切入正题。认证与授权,是整个安全架构的“大门”。门没锁好,后面再坚固的墙也白搭。今天我把这块拆成六个关键点聊——认证因子、密码认证、多因素认证、OAuth2.0、访问控制模型、零信任。全是我在项目中踩过坑、也填过坑的东西。
认证因子:你凭什么证明你是谁
认证因子分三类,说白了就是:你知道的、你拥有的、你本身就是的。
- 知识因子:密码、PIN码、密保答案。我最头疼的就是这种——用户记不住,写便签贴屏幕上,等于没锁门。
- 持有因子:手机验证码、硬件令牌、密钥卡。注意,短信验证码现在越来越容易被中间人劫持,我建议用基于时间的一次性密码(TOTP)。
- 生物因子:指纹、人脸、虹膜。方便,但有个坑——生物特征不可撤销。你密码泄露能改,指纹泄露了怎么办?所以别单独用。
密码认证:又爱又恨,但绕不开
密码认证是最古老的方案,也是被攻击最多的入口。我个人习惯是:绝不存明文密码。哪怕数据库被拖,也不能让攻击者拿到原始密码。
正确做法:
- 使用强哈希算法:bcrypt、scrypt、Argon2。别用MD5或SHA-1,哪怕加盐也不行——GPU暴力破解太容易了。
- 加随机盐(salt),每个用户独立。
- 限制登录尝试次数,加验证码防暴力破解。
# 伪代码示例:密码存储(bcrypt)
hashed_password = bcrypt.hash(plain_password, salt_rounds=12)
store_in_db(user_id, hashed_password)
# 验证时
if bcrypt.compare(input_password, stored_hash):
// 允许登录
else:
// 拒绝
多因素认证(MFA):加一道锁,安全翻倍
单密码太脆弱,加一个因素就能挡住绝大多数自动化攻击。MFA不是难在技术,是难在用户体验。我在项目中见过因为MFA搞得用户骂娘,最后不得不退回到单密码的案例。
常见组合优先级:
| 组合 | 安全强度 | 用户体验 | 我推荐吗 |
|---|---|---|---|
| 密码 + SMS验证码 | 中 | 高 | 过渡方案 |
| 密码 + TOTP | 高 | 中 | ✅ 推荐 |
| 密码 + 硬件密钥 (FIDO2) | 极高 | 中 | ✅ 企业场景 |
| 密码 + 生物特征 | 高(但单因素风险) | 高 | ⚠️ 需结合其他因素 |
关键原则:至少有两个不同的因子类别。别把“密码+密保问题”当双因素,因为都是知识因子。
为什么?我记得有一次安全审计,发现一个内部系统用了“密码+密保问题(你父亲的姓氏?)”,攻击者通过社工几分钟就拿到了答案。双因素形同虚设。
OAuth2.0协议:现代授权的基础
OAuth2.0不是认证协议,是授权协议。它解决的是“你想用我的资源,但你不需要我的密码”的问题。
核心角色:
- 资源所有者:用户
- 客户端:第三方应用
- 授权服务器:发放的地方
- 资源服务器:存放用户数据的地方
最常用的流程是授权码模式(Authorization Code Grant)。
- 客户端将用户导向授权服务器。
- 用户登录并同意授权。
- 授权服务器返回授权码(code),通过浏览器重定向。
- 客户端用授权码向授权服务器换取访问令牌(access )和刷新令牌(refresh )。
- 客户端携带访问令牌去资源服务器获取数据。
我踩过的坑:授权码一定要用PKCE(Proof Key for Code Exchange)增强。早期OAuth2.0没有这个,授权码被拦截后可以直接换。PKCE加了一个动态的code_verifier,让拦截者即使拿到授权码也无用。
刷新令牌的作用是让访问令牌过期后能静默续期,不用每次都让用户重新登录。但注意:刷新令牌的存储要更严格——它生命周期长,泄露风险更大。
RBAC与ABAC模型:权限到底怎么管
讲完认证和授权流程,再看权限模型。企业系统里用得最多的是两种:基于角色的访问控制(RBAC)和基于属性的访问控制(ABAC)。
| 维度 | RBAC | ABAC |
|---|---|---|
| 授权依据 | 角色(Role) | 主体、资源、环境属性 |
| 粒度 | 粗(角色内所有用户相同) | 细(可针对单个用户、时间、位置) |
| 配置复杂度 | 低 | 高(需要策略引擎) |
| 典型场景 | ERP、OA、员工权限 | 云平台、多租户、动态策略 |
RBAC适合静态、规模可控的组织。比如给“财务总监”角色分配“查看财务报表”权限。我做过一个项目,一开始用RBAC挺舒服,但随着业务复杂(有的报表只能给特定区域的经理看),角色开始爆炸,“角色蔓延”就来了。
这时候ABAC更灵活。策略像这样写:
if user.role == 'manager' AND resource.region == user.region AND current_time IN business_hours THEN grant read
但ABAC的代价是需要一个成熟的策略决策点(PDP),每次请求都得计算一次。我建议先上RBAC,等角色多到管理不了再引入ABAC做补充,别一上来就全上。
零信任思想:默认不信任,持续验证
零信任不是一套产品,是一种安全思维。说白了:不再信任内网,不再认为“你在办公室接上内网就安全”。
核心原则:
- 永不信任,始终验证:每次访问都认证、授权、加密。
- 最小权限:只给必要的访问权限,用完了就回收。
- 微隔离:网络分段到单个工作负载级别,攻击者横向移动的每一步都卡住。
- 持续监控与评估:信任不是一次性的,如果用户行为异常(比如半夜从国外IP登录),立刻降权或阻断。
我曾经在一个上云的企业里做零信任落地。第一步就是把所有内部应用改造成OAuth2.0 + MFA,再配合SDP(软件定义边界)隐藏真实IP。最终效果是,即使攻击者拿到了一个员工的VPN凭据,也只能访问到被授权的那一台虚拟机,无法像以前那样在内网到处扫。
零信任的落地是渐进式的。别想着一步到位,先选一个核心应用做试点,再推广。我见过最失败的案例是采购了一堆零信任设备,但业务还是用IP白名单互相访问——等于零信任的门上挂了个传统信任的锁。
最后总结一句:身份认证与访问控制没有“银弹”。密码认证要防泄露,MFA要防被绕过,OAuth2.0要防授权码被截,权限模型要防角色膨胀,零信任要防落地变形。每一步都有坑,但每一步都值得做好。