跳到主要内容

2. 'Basic' 认证方案 (The 'Basic' Authentication Scheme)

Basic authentication scheme 基于这样的模型: 对于每个 protection space ("realm"), 客户端都需要使用 user-id 和 password 对自身进行认证. realm 值是一个自由格式字符串, 只能与该服务器上的其他 realms 做相等比较. 只有当服务器能够验证适用于所请求资源的 protection space 的 user-id 和 password 时, 才会服务该请求.

Basic authentication scheme 使用 Authentication Framework 的方式如下.

在 challenges 中:

  • scheme 名称为 "Basic".
  • authentication parameter 'realm' 是 REQUIRED ([RFC7235] 第 2.2 节).
  • authentication parameter 'charset' 是 OPTIONAL (见第 2.1 节).
  • 未定义其他 authentication parameters. 接收方MUST忽略未知参数, 新参数只能通过修订本规范来定义.

另见 [RFC7235] 第 4.1 节, 其中讨论了正确解析 challenges 的复杂性.

请注意, scheme 和 parameter 名称均按大小写不敏感方式匹配.

对于 credentials, 使用 [RFC7235] 第 2.1 节定义的 "token68" 语法. 其值根据下文定义的 user-id 和 password 计算.

当服务器收到 protection space 内某 URI 的请求且该请求缺少 credentials 时, 服务器可以使用 401 (Unauthorized) 状态码 ([RFC7235] 第 3.1 节) 和 WWW-Authenticate 头字段 ([RFC7235] 第 4.1 节) 返回 challenge.

例如:

HTTP/1.1 401 Unauthorized
Date: Mon, 04 Feb 2014 16:50:53 GMT
WWW-Authenticate: Basic realm="WallyWorld"

其中 "WallyWorld" 是服务器分配的用于标识 protection space 的字符串.

代理可以使用 407 (Proxy Authentication Required) 状态码 ([RFC7235] 第 3.2 节) 和 Proxy-Authenticate 头字段 ([RFC7235] 第 4.3 节) 返回类似 challenge.

为了获得授权, 客户端:

  1. 从用户获取 user-id 和 password,
  2. 通过连接 user-id, 单个冒号 (":") 字符和 password 来构造 user-pass,
  3. 将 user-pass 编码为 octet sequence (关于字符编码方案的讨论见下文),
  4. 并使用 Base64 ([RFC4648] 第 4 节) 将该 octet sequence 编码为 US-ASCII 字符序列 ([RFC0020]), 从而得到 basic-credentials.

该认证方案的原始定义未指定用于将 user-pass 转换为 octet sequence 的字符编码方案. 实践中, 大多数实现选择了特定 locale 的编码, 例如 ISO-8859-1 ([ISO-8859-1]), 或 UTF-8 ([RFC3629]). 出于向后兼容原因, 只要默认编码与 US-ASCII 兼容, 即将任意 US-ASCII 字符映射为与 US-ASCII 字符码匹配的单个 octet, 本规范继续让默认编码保持未定义.

user-id 和 password MUST NOT包含任何控制字符 (见 [RFC5234] 附录 B.1 中的 "CTL").

此外, 包含冒号字符的 user-id 无效, 因为 user-pass 字符串中的第一个冒号用于分隔 user-id 和 password. 第一个冒号之后的文本属于 password. 包含冒号的 user-ids 不能编码在 user-pass 字符串中.

请注意, 许多 user agents 会生成 user-pass 字符串, 但并不检查用户提供的 user-id 是否包含冒号. 接收方随后会把用户名输入的一部分当作 password 的一部分.

如果 user agent 希望发送 user-id "Aladdin" 和 password "open sesame", 它会使用以下头字段:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

2.1. 'charset' auth-param

在 challenges 中, 服务器可以使用 'charset' authentication parameter 指示它期望 user agent 在生成 "user-pass" (octet 序列) 时使用的字符编码方案. 该信息纯粹是建议性的.

唯一允许的值是 "UTF-8"; 它按大小写不敏感方式匹配 (见 [RFC2978] 第 2.3 节). 它表示服务器期望字符数据先转换为 Unicode Normalization Form C ("NFC"; 见 [RFC5198] 第 3 节), 再使用 UTF-8 字符编码方案 ([RFC3629]) 编码为 octets.

对于 user-id, 接收方MUST支持 [RFC7613] 第 3.3 节定义的 "UsernameCasePreserved" profile 中的所有字符, 但冒号 (":") 字符除外.

对于 password, 接收方MUST支持 [RFC7613] 第 4.2 节定义的 "OpaqueString" profile 中的所有字符.

其他值保留供将来使用.

注意: 'charset' 仅定义在 challenges 上, 因为 Basic authentication 对 credentials 使用单个 token ('token68' 语法). 因此, credentials 语法不可扩展.

注意: 名称 'charset' 是为了与 [RFC2831] 第 2.1.1 节保持一致而选择的. 更好的名称本应是 'accept-charset', 因为它不是关于其所在消息, 而是关于服务器期望.

在下面的示例中, 服务器在 "foo" realm 中提示认证, 使用 Basic authentication, 并偏好 UTF-8 字符编码方案:

WWW-Authenticate: Basic realm="foo", charset="UTF-8"

请注意, parameter value 可以是 token 或 quoted string. 在此例中, 服务器选择使用 quoted-string 表示法.

用户名称为 "test", password 是字符串 "123" 后跟 Unicode 字符 U+00A3 (POUND SIGN). 使用 UTF-8 字符编码方案时, user-pass 变为:

't' 'e' 's' 't' ':' '1' '2' '3' pound
74 65 73 74 3A 31 32 33 C2 A3

对该 octet sequence 使用 Base64 ([RFC4648] 第 4 节) 编码得到:

dGVzdDoxMjPCow==

因此, Authorization 头字段为:

Authorization: Basic dGVzdDoxMjPCow==

或者, 对于 proxy authentication:

Proxy-Authorization: Basic dGVzdDoxMjPCow==

2.2. 复用凭据

给定已认证请求的 absolute URI ([RFC3986] 第 4.3 节), 该请求的 authentication scope 通过移除 path component 中最后一个斜杠 ("/") 字符之后的所有字符获得 ("hier_part"; 见 [RFC3986] 第 3 节). 客户端SHOULD假定, URI 与 authentication scope 做 prefix-match 的资源也位于该已认证请求的 realm 值所指定的 protection space 内.

客户端MAY在没有收到服务器另一个 challenge 的情况下, 对该空间中的资源请求预先发送相应的 Authorization 头字段. 类似地, 当客户端向代理发送请求时, 它MAY在没有收到代理服务器另一个 challenge 的情况下, 在 Proxy-Authorization 头字段中复用 user-id 和 password.

例如, 给定到以下 URI 的已认证请求:

http://example.com/docs/index.html

对以下 URI 的请求可以使用已知 credentials:

http://example.com/docs/
http://example.com/docs/test.doc
http://example.com/docs/?page=1

而以下 URI:

http://example.com/other/
https://example.com/docs/

将被视为位于 authentication scope 之外.

请注意, 一个 URI 可以属于多个 authentication scopes, 例如 "http://example.com/" 和 "http://example.com/docs/". 本规范没有定义其中哪一个应当被赋予更高优先级.