面试追问地图
| 主问题 | 必讲关键点 | 下一层追问 |
|---|---|---|
| 认证/授权 | 身份与权限分离 | 数据权限、越权、最小权限 |
| Session | 服务端状态、Session ID | 集群共享、固定攻击、强制下线 |
| JWT | 声明、签名、有效期 | 算法限制、密钥轮换、撤销 |
| Access/Refresh Token | 短期访问、长期换新 | Refresh Token 轮换和重放检测 |
| OAuth 2.0 | 四个角色、委托授权 | state、redirect_uri、客户端类型 |
| PKCE | verifier/challenge 绑定 | 为什么不能替代 state |
| OIDC | ID Token、身份声明 | Access Token 与 ID Token 能否混用 |
| SSO | 统一认证、票据、本地会话 | 单点登出、跨域 Cookie |
| XSS/CSRF | 脚本执行 vs 借用登录态 | HttpOnly、SameSite、CSP 的边界 |
| 密码存储 | 慢哈希、盐、成本参数 | 密码迁移、撞库和限速 |
| 常见 Web 攻击 | SQL 注入、401/403、API 安全 | 输入过滤、最小权限、鉴权失败处理 |
安全题应从攻击者能力出发说明防护,不能把 Base64、哈希、签名和加密混为一谈。
一、认证与授权
认证和授权有什么区别?
- 认证 Authentication:确认用户是谁。
- 授权 Authorization:确认用户可以做什么。
典型流程是先认证获得身份,再根据角色、权限、资源归属和业务规则授权。
RBAC 和 ABAC 的区别?
- RBAC:用户绑定角色,角色绑定权限,简单易维护。
- ABAC:根据用户、资源、环境等属性动态决策,更灵活但规则复杂。
实际系统常以 RBAC 为主,再补充数据权限和资源归属判断。
水平越权 vs 垂直越权(IDOR)
频次 ★★★ · 难度 🟡 · 高频:阿里/字节
越权(Broken Access Control) 是 OWASP Top 10 中最常见的漏洞之一,分为两类:
| 类型 | 定义 | 示例 |
|---|---|---|
| 水平越权 | 用户 A 访问同级别用户 B 的资源 | 用户 A 修改 URL 中 userId=123 为 userId=456,查看他人的订单 |
| 垂直越权 | 普通用户访问管理员功能 | 普通用户直接访问 /admin/deleteUser API |
IDOR(Insecure Direct Object Reference) 是越权的子集——攻击者直接引用内部对象 ID(数据库自增 ID、订单号)且服务端未校验归属。IDOR = 数字型 ID + 缺少归属校验。
防御方案:
- 资源归属校验(关键):每个 API 校验当前用户是否有权限操作目标资源。框架层拦截器 + 注解,避免逐业务重复写
// 注解示例 —— SpEL 表达式自动校验
@PreAuthorize("#order.userId == #currentUserId")
public Order getOrder(@Param("order") Order order) { ... }- 可猜测 ID → 不透明 ID:用 UUID 或哈希 ID 替代自增 ID,但不是核心防御(归属校验才是)
- 权限矩阵:明确每个接口的角色/权限要求,默认拒绝
- 水平/垂直分别防御:水平靠资源归属,垂直靠 RBAC 角色检查
数据库层面:大多数数据天然带 user_id/tenant_id 字段,查询时作为隐含条件加到 SQL 中(多租户模式)。
二、Cookie、Session 与 Token
Cookie 和 Session 的区别?
难度 🟡
| Cookie | Session | |
|---|---|---|
| 存储位置 | 客户端 | 服务端 |
| 传输 | 浏览器自动携带 | 通常通过 Cookie 中的 Session ID 定位 |
| 风险 | XSS、CSRF、泄露 | 会话劫持、固定攻击、服务端存储压力 |
| 集群 | Cookie 天然随请求 | 需要粘性会话或共享 Session |
Cookie 可设置 HttpOnly、Secure、SameSite 降低风险。
Session 集群部署如何处理?
- 负载均衡粘性会话:简单但故障迁移和扩容不友好。
- Redis 共享 Session:常见,需考虑 Redis 可用性和过期策略。
- 使用无状态 Token:减少会话存储,但引入撤销和密钥治理问题。
Token 和 Session 如何选择?
Session 适合服务端可控、需要随时撤销的 Web 会话;Token 适合 API、多服务和跨域调用。
无状态不是绝对优势。需要强制下线、设备管理和风险控制时,Token 方案往往仍需要服务端状态。
三、JWT
JWT 的结构是什么?
难度 🟡
JWT 通常由三部分组成:
Header.Payload.Signature- Header:签名算法、令牌类型。
- Payload:声明,如
sub、iss、aud、exp、iat、jti。 - Signature:防止令牌被篡改。
JWT 默认只是 Base64URL 编码,不是加密,Payload 不应存放密码和敏感信息。
JWT 验证需要检查什么?
- 签名是否合法,并限制允许的算法。
exp是否过期。nbf是否已生效。iss是否为可信签发方。aud是否包含当前服务。- 必要时检查
jti、用户状态和令牌版本。
不能只解码 Payload 就认为认证成功。
JWT 有哪些缺点?
- 签发后难以立即撤销。
- Payload 过大会增加每次请求开销。
- 权限变更不能立即反映到旧令牌。
- 密钥轮换和多服务验签管理复杂。
常见方案是短期 Access Token + 长期 Refresh Token,并配合黑名单、令牌版本或服务端会话。
Access Token 和 Refresh Token 如何配合?
- Access Token 生命周期短,用于访问资源。
- Refresh Token 生命周期长,只用于换取新的 Access Token。
Refresh Token 应安全存储、支持撤销和轮换。检测到旧 Refresh Token 被重复使用时,应视为可能泄露并终止令牌链。
JWT 泄露后怎么办?
- 立即撤销 Refresh Token 和相关会话。
- 将 Access Token 的
jti加入短期黑名单,或提升用户令牌版本。 - 缩短 Access Token 有效期。
- 轮换受影响的签名密钥。
- 审计异常 IP、设备和敏感操作。
四、OAuth 2.0 与 OIDC
OAuth 2.0 解决什么问题?
难度 🔴
OAuth 2.0 是授权框架,让用户允许第三方应用在限定范围内访问资源,而不需要把账号密码交给第三方。
主要角色:
- Resource Owner:资源所有者。
- Client:第三方客户端。
- Authorization Server:授权服务器。
- Resource Server:资源服务器。
授权码模式的基本流程?
客户端跳转授权服务器
↓
用户登录并授权
↓
客户端收到一次性 Authorization Code
↓
后端用 Code + PKCE/客户端凭证换 Token
↓
携带 Access Token 访问资源服务授权码应短期、一次性并绑定客户端与重定向地址。
PKCE 解决什么问题?
PKCE 通过 code_verifier 和 code_challenge 将授权码绑定到发起请求的客户端,防止授权码被截获后直接兑换 Token。
它对移动端、桌面端、SPA 等无法安全保存客户端密钥的公共客户端尤其重要。
OAuth 2.0 和 OIDC 的区别?
- OAuth 2.0:解决授权。
- OIDC:在 OAuth 2.0 之上增加身份认证,返回 ID Token 和标准用户信息。
“使用 OAuth 登录”通常实际指 OIDC 或厂商扩展的身份接口。
五、单点登录
开放 API 签名、防重放、接口版本和幂等设计见 API设计与接口治理。
单点登录 SSO 如何实现?
核心是多个业务系统信任统一身份中心:
- 用户访问业务系统,未登录时跳转身份中心。
- 身份中心完成认证。
- 返回一次性票据或授权码。
- 业务系统后端校验并建立本地会话。
常见协议包括 OIDC、SAML 和 CAS。
单点登出为什么更复杂?
登录只需要建立信任,登出需要通知所有已建立会话的系统。可能采用:
- 前端逐个跳转注销。
- 身份中心向各系统发送后端注销通知。
- 短会话 + 定期检查统一会话状态。
必须明确“退出当前系统”“退出当前设备”和“退出所有设备”的语义。
六、常见 Web 攻击
XSS 是什么?如何防护?
攻击者将恶意脚本注入页面,在用户浏览器执行。
防护:
- 按输出上下文编码。
- 使用安全模板,避免拼接 HTML。
- 设置 CSP。
- Cookie 设置
HttpOnly。 - 富文本使用白名单清洗。
CSRF 是什么?如何防护?
攻击者诱导已登录用户的浏览器自动携带 Cookie 发起非预期请求。
防护:
- CSRF Token。
- Cookie 设置合适的
SameSite。 - 校验 Origin/Referer。
- 敏感操作二次确认。
- 不使用 GET 修改数据。
SQL 注入如何防护?
- 使用预编译参数,不拼接用户输入。
- 动态表名和排序字段使用白名单。
- 数据库账号遵循最小权限。
- 不把详细数据库错误返回客户端。
401 和 403 的区别?
401 Unauthorized:未认证或凭证无效,实际语义更接近“需要认证”。403 Forbidden:身份已知,但没有访问权限。
七、密码与密钥
密码应该如何存储?
不能明文存储,也不应使用普通快速哈希。
应使用带随机盐、成本可调的密码哈希算法,如 bcrypt、scrypt 或 Argon2,并支持逐步提升成本参数。
签名密钥如何管理?
- 不写入代码和镜像。
- 使用密钥管理系统或 Secret 管理。
- 配置密钥 ID,支持平滑轮换。
- 限制访问权限并记录审计日志。
- 区分不同环境、用途和算法的密钥。