身份认证与访问控制

咱们直接切入正题。认证与授权,是整个安全架构的“大门”。门没锁好,后面再坚固的墙也白搭。今天我把这块拆成六个关键点聊——认证因子、密码认证、多因素认证、OAuth2.0、访问控制模型、零信任。全是我在项目中踩过坑、也填过坑的东西。

认证因子:你凭什么证明你是谁

认证因子分三类,说白了就是:你知道的、你拥有的、你本身就是的。

  • 知识因子:密码、PIN码、密保答案。我最头疼的就是这种——用户记不住,写便签贴屏幕上,等于没锁门。
  • 持有因子:手机验证码、硬件令牌、密钥卡。注意,短信验证码现在越来越容易被中间人劫持,我建议用基于时间的一次性密码(TOTP)。
  • 生物因子:指纹、人脸、虹膜。方便,但有个坑——生物特征不可撤销。你密码泄露能改,指纹泄露了怎么办?所以别单独用。
避坑:我在做金融系统时,遇到过把“人脸+密码”当成双因素认证的案例。但人脸和密码都属于“你记的/你本身的”?严格算单因素偏弱。双因素必须跨类别组合。

密码认证:又爱又恨,但绕不开

密码认证是最古老的方案,也是被攻击最多的入口。我个人习惯是:绝不存明文密码。哪怕数据库被拖,也不能让攻击者拿到原始密码。

正确做法:

  1. 使用强哈希算法:bcrypt、scrypt、Argon2。别用MD5或SHA-1,哪怕加盐也不行——GPU暴力破解太容易了。
  2. 加随机盐(salt),每个用户独立。
  3. 限制登录尝试次数,加验证码防暴力破解。
# 伪代码示例:密码存储(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)。

  1. 客户端将用户导向授权服务器。
  2. 用户登录并同意授权。
  3. 授权服务器返回授权码(code),通过浏览器重定向。
  4. 客户端用授权码向授权服务器换取访问令牌(access )和刷新令牌(refresh )。
  5. 客户端携带访问令牌去资源服务器获取数据。

我踩过的坑:授权码一定要用PKCE(Proof Key for Code Exchange)增强。早期OAuth2.0没有这个,授权码被拦截后可以直接换。PKCE加了一个动态的code_verifier,让拦截者即使拿到授权码也无用。

刷新令牌的作用是让访问令牌过期后能静默续期,不用每次都让用户重新登录。但注意:刷新令牌的存储要更严格——它生命周期长,泄露风险更大。

RBAC与ABAC模型:权限到底怎么管

讲完认证和授权流程,再看权限模型。企业系统里用得最多的是两种:基于角色的访问控制(RBAC)和基于属性的访问控制(ABAC)。

维度RBACABAC
授权依据角色(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白名单互相访问——等于零信任的门上挂了个传统信任的锁。

本章知识体系:身份认证与访问控制 认证因子 知识/持有/生物 密码认证 (bcrypt) 多因素认证 (MFA) TOTP/SMS/FIDO2 授权协议 OAuth2.0 授权码模式 PKCE 防拦截 Refresh 续期 (非认证,是授权) 访问控制模型 RBAC(基于角色) ABAC(基于属性) 最小权限原则 角色蔓延问题 零信任思想(底层基石) 永不信任,始终验证 持续评估信任等级 微隔离 & 最小权限 所有访问都需要认证+授权+加密 零信任不是独立模块,而是贯穿认证、授权、访问控制全流程的安全思想

最后总结一句:身份认证与访问控制没有“银弹”。密码认证要防泄露,MFA要防被绕过,OAuth2.0要防授权码被截,权限模型要防角色膨胀,零信任要防落地变形。每一步都有坑,但每一步都值得做好。