JavaGuide 官方知识星球

这部分内容摘自 JavaGuide 下面几篇文章的重点:

JavaGuide

认证授权基础概念详解

认证授权基础概念详解

JWT 基础概念详解

JWT 基础概念详解

JWT 优缺点分析

JWT 优缺点分析

SSO 单点登录详解

SSO 单点登录详解

权限系统设计详解

权限系统设计详解

认证与会话

认证与会话

⭐️认证和授权有什么区别?

⭐️认证和授权有什么区别?

认证(Authentication):确认访问者是谁,例如使用密码、短信验证码、Passkey 或客户端证书验证身份。

授权(Authorization):确认当前身份可以访问哪些资源、执行哪些操作。

认证通常发生在授权之前,但“已经登录”不代表“拥有所有权限”。服务端收到请求后,既要确认身份,还要结合操作、资源归属、租户和数据范围做授权判断。

常见的认证因素有哪些?什么是 MFA?

常见的认证因素有哪些?什么是 MFA?

认证因素通常分为三类:

你知道的信息:密码、PIN。

你拥有的东西:手机、硬件安全密钥、一次性验证码设备。

你的生物特征:指纹、人脸等。

MFA(Multi-Factor Authentication,多因素认证)要求使用至少两种不同类型的因素。密码加安全问题仍然属于同一类“知道的信息”,不能算真正的双因素认证。

短信验证码使用方便,但会受到 SIM 卡换卡、短信劫持和钓鱼影响。对管理员、支付、改密等高风险操作,更适合使用 TOTP、Passkey 或硬件安全密钥,并结合风险识别和重新认证。

Cookie 和 Session 有什么区别?

Cookie 和 Session 有什么区别?

Cookie 是浏览器保存并按规则自动随请求发送的数据;Session 是服务端维护的一段会话状态。两者经常组合使用:服务端创建 Session,把没有业务含义的随机 SessionId 放进 Cookie,后续再通过它查找会话。

SessionId

对比项CookieSession保存位置客户端服务端或共享会话存储常见内容SessionId、偏好设置用户 ID、登录状态、会话属性主要风险窃取、篡改、作用域配置不当会话固定、劫持、过期和存储压力

对比项CookieSession

对比项

Cookie

Session

保存位置客户端服务端或共享会话存储

保存位置

客户端

服务端或共享会话存储

常见内容SessionId、偏好设置用户 ID、登录状态、会话属性

常见内容

SessionId、偏好设置

用户 ID、登录状态、会话属性

主要风险窃取、篡改、作用域配置不当会话固定、劫持、过期和存储压力

主要风险

窃取、篡改、作用域配置不当

会话固定、劫持、过期和存储压力

“Session 保存在服务端”不等于绝对安全。攻击者拿到有效 SessionId 后,仍可能直接冒充用户。

SessionId

⭐️Session-Cookie 认证流程是什么?

⭐️Session-Cookie 认证流程是什么?

用户提交登录凭据,服务端完成身份验证。

服务端创建 Session,并生成随机、不可预测的 SessionId。

SessionId

服务端通过 Set-Cookie 把 SessionId 交给浏览器。

Set-Cookie
SessionId

浏览器在符合 Cookie 作用域的请求中自动携带它。

服务端查找 Session,恢复用户身份,再执行权限校验。

Session 配合 Cookie 保存用户登录状态的流程

会话 Cookie 一般要配置 HttpOnly、Secure、合适的 SameSite、Path 和过期时间。登录成功、权限提升或敏感操作重新认证后应更换 Session ID,避免会话固定攻击;退出登录时要让服务端会话失效。

HttpOnly
Secure
SameSite
Path

分布式环境下如何管理 Session?

分布式环境下如何管理 Session?

常见方案有三种:

会话粘滞:同一用户尽量路由到固定实例。实现简单,但实例故障会丢失本地会话,扩缩容也更麻烦。

节点间复制:实例相互同步 Session。节点越多,同步和一致性成本越高。

集中存储:把 Session 放入 Redis 等共享存储,应用实例保持无状态。这是常见做法,但需要处理共享存储的高可用、过期和容量。

Spring 项目可以使用 Spring Session 接入 Redis 等外部存储。无论采用哪种方案,Session 的有效期、主动注销、踢下线和权限变更都要有统一管理机制。

Session 和 Token 认证如何选择?

Session 和 Token 认证如何选择?

Session 方案由服务端保存会话状态,撤销、踢下线和权限即时变更更直接;代价是服务端需要存储和查询会话。

Token 是客户端携带的访问凭据。Token 可以是随机字符串,也可以是 JWT。随机 Token 通常仍要查询服务端状态;自包含 JWT 可以减少会话查询,但会增加撤销、权限变更和密钥管理难度。

选择时应看应用形态和安全要求:传统 Web 应用常用 Cookie + Session 或 BFF;开放 API、移动端和跨服务调用常用 Bearer Token。两种方案都必须使用 HTTPS,并处理凭据泄露、过期和撤销。

浏览器中应该把 Token 存在哪里?

浏览器中应该把 Token 存在哪里?

不要把 localStorage 或 sessionStorage 当成认证凭据的默认存储位置。同源页面中的 JavaScript 可以读取 Web Storage,一处 XSS 漏洞就可能泄露 Access Token 和 Refresh Token。

localStorage
sessionStorage

浏览器应用常见选择是:

使用 BFF,由后端保存 OAuth Token,浏览器只持有设置了 HttpOnly、Secure 和合适 SameSite 的会话 Cookie。

HttpOnly
Secure
SameSite

直接使用 Cookie 保存短期凭据,同时做好 CSRF Token、Origin/Referer 校验等 CSRF 防护。

Origin
Referer

必须由前端持有 Token 时,尽量只放在内存,缩短有效期,并把 Refresh Token 保护放在更高优先级。

凭据放在 Cookie 中要重点防 CSRF;交给 JavaScript 管理则要重点防 XSS。存储方式改变的是主要攻击面,不会让其他风险自动消失。

JWT

JWT

⭐️什么是 JWT?它由哪些部分组成?

⭐️什么是 JWT?它由哪些部分组成?

JWT(JSON Web Token)是一种紧凑的令牌格式,常见的 JWS 形式由三部分组成:

Header.Payload.Signature
Header.Payload.Signature

Header:令牌类型和签名算法等元数据。

Payload:Claims,例如 iss、sub、aud、exp、nbf 和 jti。

iss
sub
aud
exp
nbf
jti

Signature:对 Header 和 Payload 做完整性保护,服务端据此判断内容是否被修改。

JWT 的组成

Header 和 Payload 通常只是 Base64Url 编码,任何拿到令牌的人都能解码查看。因此,Payload 不应存密码、银行卡号等秘密信息。

JWT 有签名,为什么还需要 HTTPS?

JWT 有签名,为什么还需要 HTTPS?

签名主要防止内容被未授权修改,不提供传输保密性,也不能阻止攻击者重放一个被盗但仍然有效的 JWT。

HTTPS 可以保护令牌在传输过程中不被窃听和篡改。服务端还要固定允许的算法集合,校验签名以及 iss、aud、exp、nbf 等声明,并区分 ID Token、Access Token 等不同用途,不能只做一次“能解码”检查。

iss
aud
exp
nbf

⭐️JWT 被盗后如何降低风险?

⭐️JWT 被盗后如何降低风险?

Access Token 设置较短有效期和尽量小的权限范围。

Refresh Token 单独保护,绑定客户端、授权范围和资源服务器。

使用 Refresh Token 轮换,发现旧令牌重放时撤销整条授权链。

改密、退出和账号风险事件发生时,撤销 Refresh Token 或登录会话。

对高风险接口增加重新认证、MFA、设备约束或发送者约束令牌。

仅缩短 JWT 有效期会缩小风险窗口,但不会让已经泄露的 Token 立即失效。

使用 JWT 后如何实现退出登录和强制下线?

使用 JWT 后如何实现退出登录和强制下线?

常见做法有:

客户端删除本地 Token,只能处理当前客户端主动退出。

Access Token 短期有效,服务端撤销 Refresh Token,让旧 Access Token 在较短时间后自然失效。

维护 Token 黑名单、用户会话版本号或“最早有效时间”,请求时增加一次状态检查。

使用网关或认证中心统一维护会话,向各服务传播撤销事件。

如果系统要求改密后立即让所有设备下线,就不能只依赖完全无状态、有效期很长的 JWT。撤销能力意味着服务端通常仍要保存一部分状态。

Access Token 和 Refresh Token 有什么区别?

Access Token 和 Refresh Token 有什么区别?

对比项Access TokenRefresh Token用途访问资源服务器向授权服务器换取新 Access Token有效期通常较短通常较长暴露范围会发送给资源服务器只发送给授权服务器泄露后果在有效期和权限范围内调用 API可以持续换取新 Access Token,风险更高

对比项Access TokenRefresh Token

对比项

Access Token

Refresh Token

用途访问资源服务器向授权服务器换取新 Access Token

用途

访问资源服务器

向授权服务器换取新 Access Token

有效期通常较短通常较长

有效期

通常较短

通常较长

暴露范围会发送给资源服务器只发送给授权服务器

暴露范围

会发送给资源服务器

只发送给授权服务器

泄露后果在有效期和权限范围内调用 API可以持续换取新 Access Token,风险更高

泄露后果

在有效期和权限范围内调用 API

可以持续换取新 Access Token,风险更高

Refresh Token 不一定是 JWT。公共客户端使用 Refresh Token 时,应采用轮换或发送者约束方案检测重放,并设置闲置过期和安全事件撤销。

OAuth 2.0、OIDC 与 SSO

OAuth 2.0、OIDC 与 SSO

⭐️OAuth 2.0 是什么?有哪些角色?

⭐️OAuth 2.0 是什么?有哪些角色?

OAuth 2.0 用于让客户端在资源所有者同意后,获得对受保护资源的有限访问权限。它解决的是委托授权问题。

协议中常见的四个角色是:

Resource Owner:资源所有者,通常是用户。

Client:希望访问资源的应用。

Authorization Server:完成授权并签发 Token。

Resource Server:保存受保护资源并验证 Access Token。

OAuth 2.0 第三方授权流程

“使用某平台账号登录”如果只拿 OAuth Access Token 调用用户信息接口,容易把授权和身份认证混在一起。标准的身份层应使用 OIDC,并正确校验 ID Token。

⭐️授权码模式加 PKCE 的流程是什么?

⭐️授权码模式加 PKCE 的流程是什么?

客户端生成随机 code_verifier,再计算 code_challenge。

code_verifier
code_challenge

浏览器跳转到授权服务器,请求中带上 state、code_challenge 和回调地址。

state
code_challenge

用户完成认证和授权后,授权服务器把一次性授权码返回客户端。

客户端后端或本地应用携带授权码和 code_verifier 请求 Token Endpoint。

code_verifier

授权服务器校验 PKCE,签发 Access Token,按策略决定是否签发 Refresh Token。

PKCE 让截获授权码的攻击者因为缺少 code_verifier 而无法兑换 Token。state 用于绑定授权请求与回调并防范 CSRF;回调地址必须精确匹配预先登记的地址。当前 OAuth 2.0 安全最佳实践建议授权码模式使用 PKCE,不再把它只看作移动端补丁。

code_verifier
state

OAuth 2.0 和 OIDC 有什么区别?

OAuth 2.0 和 OIDC 有什么区别?

OAuth 2.0:解决“客户端能访问哪些资源”的授权问题,核心凭据是 Access Token。

OIDC(OpenID Connect):在 OAuth 2.0 之上增加身份层,让客户端验证最终用户身份,核心新增凭据是 ID Token。

Access Token 的受众是资源服务器,不应被客户端当作用户身份证明。客户端使用 OIDC 时,需要校验 ID Token 的签名、签发方、受众、过期时间和 nonce 等字段。

nonce

什么是 SSO?如何实现跨系统单点登录?

什么是 SSO?如何实现跨系统单点登录?

SSO(Single Sign-On,单点登录)让用户在统一身份提供方完成一次登录后,可以访问多个相互信任的业务系统。

常见实现是让各业务系统分别维护自己的 host-only 会话:未登录时跳转到统一认证中心,认证中心利用自身 Cookie 判断登录状态,再通过一次性、短期授权码把认证结果返回业务系统,业务系统后端换取身份信息并建立本地会话。

单点登录系统设计

不要为了跨子域登录而直接把高权限认证 Cookie 的 Domain 扩大到整个父域。任一薄弱或被接管的子域都可能扩大凭据泄露风险。SSO 还要处理统一退出、子系统会话清理、授权撤销和认证中心高可用。

Domain

权限控制

权限控制

⭐️RBAC、ABAC 和 ACL 有什么区别?

⭐️RBAC、ABAC 和 ACL 有什么区别?

模型授权依据适合场景主要问题RBAC用户所属角色企业后台、功能权限角色可能越建越多ABAC用户、资源、环境等属性多租户、动态策略、细粒度权限规则理解和调试更复杂ACL资源对应的主体权限列表文档分享、文件权限大量资源下维护成本高

模型授权依据适合场景主要问题

模型

授权依据

适合场景

主要问题

RBAC用户所属角色企业后台、功能权限角色可能越建越多

RBAC

用户所属角色

企业后台、功能权限

角色可能越建越多

ABAC用户、资源、环境等属性多租户、动态策略、细粒度权限规则理解和调试更复杂

ABAC

用户、资源、环境等属性

多租户、动态策略、细粒度权限

规则理解和调试更复杂

ACL资源对应的主体权限列表文档分享、文件权限大量资源下维护成本高

ACL

资源对应的主体权限列表

文档分享、文件权限

大量资源下维护成本高

RBAC 权限模型

实际系统经常组合使用:RBAC 判断用户能否使用某项功能,ABAC 或数据范围规则继续判断他能操作哪个部门、租户或具体对象。

为什么前端隐藏按钮不能代替后端授权?

为什么前端隐藏按钮不能代替后端授权?

前端代码和请求参数都由客户端控制。攻击者可以手动请求接口、修改资源 ID,或者绕过页面直接调用后端。

前端隐藏菜单和按钮只用于改善交互;后端必须默认拒绝未明确授权的请求,并在每次访问时校验当前主体对目标操作和目标资源的权限。客户端传入的用户 ID、角色或租户 ID 不能直接作为可信授权依据。

⭐️只校验角色为什么还会出现越权?

⭐️只校验角色为什么还会出现越权?

角色校验通常只能回答“能否使用这个接口”,不能回答“能否操作这条数据”。例如,普通用户都能调用订单详情接口,但用户 A 不能通过修改 orderId 查看用户 B 的订单。

orderId

防止对象级越权需要把主体和资源一起放进授权条件:

SELECT id, status, amount
FROM orders
WHERE id = ?
  AND owner_id = ?;
SELECT id, status, amount
FROM orders
WHERE id = ?
  AND owner_id = ?;

后台管理场景还可能需要校验组织、区域和数据范围。对不存在和无权访问的资源,应避免返回能帮助攻击者枚举资源的差异化细节。

多租户系统如何避免跨租户访问?

多租户系统如何避免跨租户访问?

租户身份应来自服务端验证过的会话、Token 或可信网关上下文,不能直接相信请求体里的 tenantId。

tenantId

查询、更新和删除都带上租户条件,唯一约束和缓存 Key 也包含租户维度。

数据访问层统一注入租户条件,降低业务代码漏写的概率,但仍要测试批量接口、导出任务和后台任务。

管理员跨租户操作使用独立权限和审计流程,避免用普通用户链路“临时放开”。

高隔离要求可以采用独立 Schema、数据库或实例,并配套迁移和运维方案。

仅在网关校验一次租户还不够。异步消息、定时任务、缓存和搜索索引同样需要携带并校验租户上下文。

权限变更后,如何让缓存中的旧权限及时失效?

权限变更后,如何让缓存中的旧权限及时失效?

常见方案是给用户或租户维护权限版本号:登录态记录版本,请求时与当前版本比较;角色或权限变化后递增版本,使旧登录态失效。也可以删除权限缓存并通过消息通知各节点刷新。

权限缓存应设置过期时间,并保证撤权失败可重试。涉及资金、审批和管理员操作时,可以在执行前查询权威权限服务,不依赖长时间缓存。还要记录谁在什么时间给谁授予或撤销了什么权限,便于审计和追踪。

参考资料

参考资料

OWASP Authentication Cheat Sheet

OWASP Authentication Cheat Sheet

OWASP Authorization Cheat Sheet

OWASP Authorization Cheat Sheet

OWASP Session Management Cheat Sheet

OWASP Session Management Cheat Sheet

RFC 9700:Best Current Practice for OAuth 2.0 Security

RFC 9700:Best Current Practice for OAuth 2.0 Security

OpenID Connect Core 1.0

OpenID Connect Core 1.0

写在最后

写在最后

感谢你能看到这里,也希望这篇文章对你有点用。

JavaGuide 坚持更新 6 年多,近 6000 次提交、600+ 位贡献者一起打磨。如果这些内容对你有帮助,非常欢迎点个免费的 Star 支持下(完全自愿,觉得有收获再点就好):GitHub | Gitee。

GitHub

Gitee

如果你想要付费支持/面试辅导(比如简历优化、一对一提问、高频考点突击资料等)的话,欢迎了解我的知识星球。已经坚持维护六年,内容持续更新,虽白菜价(0.4元/天)但质量很高,主打一个良心!

知识星球

JavaGuide 公众号