跳到主要内容

RFC 7235 - HTTP/1.1: 认证 (Authentication)

  • 状态: Proposed Standard
  • 发布日期: June 2014
  • Stream: IETF
  • 废止: RFC2616 (部分), RFC2617 (部分)
  • 被废止: RFC9110
  • 勘误: 无勘误

文档信息

  • RFC 编号: 7235
  • 标题: Hypertext Transfer Protocol (HTTP/1.1): Authentication
  • 中文标题: 超文本传输协议 (HTTP/1.1): 认证
  • 发布日期: 2014 年 6 月
  • 作者: R. Fielding (Adobe), J. Reschke (greenbytes)
  • 状态: Standards Track

注意: 本文档材料已被 [RFC 9110] 吸收与取代.

摘要 (Abstract)

HTTP 提供简单的质询-响应认证框架, 使服务器能够质询客户端请求, 并使客户端能够提供凭证. 本文档定义 HTTP 认证框架的一般机制, 包括 401、407 状态码以及相关头字段.

核心概念

HTTP 认证流程

1. 客户端请求受保护资源
→ GET /admin HTTP/1.1

2. 服务器返回质询
← HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Admin Area"

3. 客户端提供凭证
→ GET /admin HTTP/1.1
Authorization: Basic dXNlcjpwYXNzd29yZA==

4. 服务器验证并响应
← HTTP/1.1 200 OK
[受保护内容...]

认证方案 (Authentication Schemes)

HTTP 支持多种认证方案:

  • Basic: 基本认证 (RFC 7617)
  • Bearer: Bearer 令牌 (RFC 6750)
  • Digest: 摘要认证 (RFC 7616)
  • OAuth: OAuth 认证 (RFC 6749)

401 Unauthorized

表示请求未包含有效认证凭证.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="WallyWorld"
Content-Type: text/html
Content-Length: 0

重要: 401 的名称 "Unauthorized" 在实践中常表示 Unauthenticated (未认证).

407 Proxy Authentication Required

表示客户端必须先向代理认证.

HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="Proxy Access"

WWW-Authenticate 头

服务器用此头定义认证质询.

基本语法

WWW-Authenticate: <scheme> realm="<realm>" [, <param>=<value>]*

示例

单一质询:

WWW-Authenticate: Basic realm="Admin Area"

多个质询 (客户端可选择):

WWW-Authenticate: Bearer realm="API", Basic realm="API"

带附加参数:

WWW-Authenticate: Digest
realm="[email protected]",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"

realm 参数

realm (域/保护空间) 定义保护范围:

WWW-Authenticate: Basic realm="管理员区域"
  • 通常显示在浏览器认证对话框中
  • 帮助用户理解需要哪些凭证
  • 同一 realm 的资源共享凭证缓存策略

Authorization 头

客户端用此头提供认证信息.

基本语法

Authorization: <scheme> <credentials>

示例

Basic 认证:

Authorization: Basic dXNlcjpwYXNzd29yZA==

Bearer 令牌:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Digest 认证:

Authorization: Digest username="user",
realm="[email protected]",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri="/dir/index.html",
response="6629fae49393a05397450978507c4ef1"

Proxy-Authenticate 与 Proxy-Authorization

用于代理认证, 功能类似 WWW-Authenticate 与 Authorization.

代理认证流程

1. 客户端请求
→ GET http://example.com/ HTTP/1.1

2. 代理要求认证
← HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="Proxy"

3. 客户端提供凭证
→ GET http://example.com/ HTTP/1.1
Proxy-Authorization: Basic cHJveHk6cGFzc3dvcmQ=

4. 代理转发请求
[Proxy] → GET / HTTP/1.1
Host: example.com

Basic 认证 (RFC 7617)

最简单但安全性最差的认证方案之一.

凭证编码

// 1. 组合用户名与密码
const credentials = "username:password";

// 2. Base64 编码
const encoded = btoa(credentials);
// 结果: "dXNlcm5hbWU6cGFzc3dvcmQ="

// 3. 构造 Authorization 头
const auth = `Basic ${encoded}`;

完整示例

GET /admin HTTP/1.1
Host: example.com
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

安全警告

危险: Basic 认证以 Base64 编码发送凭证. 这不是加密!

dXNlcm5hbWU6cGFzc3dvcmQ=
↓ Base64 解码
username:password

必须使用 HTTPS:

✗ http://example.com + Basic = 明文发送
✓ https://example.com + Basic = 加密传输

Bearer 令牌认证 (RFC 6750)

现代 Web API 常用的认证方案.

使用场景

通常与 OAuth 2.0 一起使用:

1. 用户登录并获取访问令牌
← { "access_token": "eyJhbG...", "token_type": "Bearer" }

2. 使用令牌访问 API
→ GET /api/user HTTP/1.1
Authorization: Bearer eyJhbG...

示例

GET /api/resource HTTP/1.1
Host: api.example.com
Authorization: Bearer mF_9.B5f-4.1JqM

错误响应

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="API",
error="invalid_token",
error_description="The access token expired"

Digest 认证 (RFC 7616)

比 Basic 更安全, 但更复杂.

特点

  • 不直接发送密码
  • 使用质询-响应机制
  • 通过 nonce 防止重放攻击

简化流程

1. 服务器发送质询 (含 nonce)
← WWW-Authenticate: Digest realm="...", nonce="..."

2. 客户端计算响应
response = MD5(
MD5(username:realm:password) :
nonce :
MD5(method:uri)
)

3. 客户端发送响应
→ Authorization: Digest username="...", response="..."

实际应用场景

场景 1: Web 应用登录

传统表单 + Session (推荐):

POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=user&password=pass

→ HTTP/1.1 302 Found
Set-Cookie: sessionid=abc123; HttpOnly; Secure

不要使用 HTTP Basic (除非经 HTTPS).

场景 2: API 认证

Bearer Token (推荐):

GET /api/users HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

场景 3: 保护管理界面

Basic + HTTPS (简单场景):

GET /admin HTTP/1.1
Host: secure.example.com
Authorization: Basic YWRtaW46c2VjcmV0

场景 4: 微服务间认证

相互 TLS + Bearer Token:

GET /internal/service HTTP/1.1
Host: internal.example.com
Authorization: Bearer service-token-123

认证 vs. 授权

区别

认证 (Authentication): "你是谁?"

Authorization: Bearer [身份令牌]

授权 (Authorization): "你能做什么?"

令牌中包含的权限:
{
"user_id": "123",
"roles": ["admin", "editor"],
"permissions": ["read", "write", "delete"]
}

HTTP 状态码

  • 401 Unauthorized: 认证失败或缺少认证
  • 403 Forbidden: 已认证, 但无权限
用户 A 尝试访问管理员资源:
→ 未登录 → 401 Unauthorized
→ 已登录 (普通用户) → 403 Forbidden
→ 已登录 (管理员) → 200 OK

最佳实践

服务器侧

  1. 始终使用 HTTPS
  2. 提供清晰的 realm
  3. 支持多种认证方案
  4. 限制失败尝试 (速率限制, 日志, 临时锁定)
  5. 安全存储凭证 (bcrypt/Argon2 哈希, 安全随机令牌)

客户端侧

  1. 安全存储令牌
  2. 处理 401 响应 (清除令牌, 重定向登录)
  3. 在过期前刷新令牌

安全考虑

1. 中间人攻击

风险: 未加密传输凭证

防御: 使用 HTTPS

2. 重放攻击

风险: 攻击者截获并重放认证请求

防御: 短期令牌, nonce, 令牌与客户端绑定

3. 凭证泄露

风险: 凭证出现在日志或 URL 中

防御:

✗ https://api.example.com/data?token=abc123
✓ Authorization: Bearer abc123

4. XSS 攻击

风险: 恶意脚本窃取令牌

防御: HttpOnly Cookie, CSP, 输入校验

规范章节对照

章节内容
1引言
2访问认证框架, 质询/响应, realm
3401, 407
4WWW-Authenticate, Authorization, Proxy-*
5IANA
6安全考虑
附录 A相对 RFC 2616/2617 的变更

总结

HTTP 认证提供灵活的框架:

  • 可靠性: 正确实现认证协议以保障安全
  • 清晰性: 明确表达认证需求, 便于客户端实现
  • 实用性: 优雅设计认证流程, 改善用户体验

核心原则:

  1. 始终使用 HTTPS
  2. 按场景选择合适方案
  3. 多层防御
  4. 定期轮换凭证

现代建议:

  • Web 应用: OAuth 2.0 + OpenID Connect
  • API: Bearer Token (JWT)
  • 简单场景: Basic + HTTPS
  • 尽量避免: Digest (陈旧且复杂)

相关资源