Skip to main content

2. 'Basic' 认证方案

Basic 认证方案基于这样的模型:客户端需要为每个保护空间("领域")使用用户 ID 和密码进行身份验证。领域值是一个自由格式字符串,只能与该服务器上的其他领域进行相等性比较。只有当服务器能够验证应用于所请求资源的保护空间的用户 ID 和密码时,服务器才会处理该请求。

Basic 认证方案按以下方式利用认证框架。

在质询中:

  • 方案名称是 "Basic"。
  • 认证参数 'realm' 是必需的(REQUIRED)([RFC7235],第 2.2 节)。
  • 认证参数 'charset' 是可选的(OPTIONAL)(参见第 2.1 节)。
  • 未定义其他认证参数 —— 接收方必须(MUST)忽略未知参数,新参数只能通过修订本规范来定义。

另请参阅 [RFC7235] 的第 4.1 节,其中讨论了正确解析质询的复杂性。

请注意,方案名称和参数名称的匹配不区分大小写。

对于凭据,使用 [RFC7235] 第 2.1 节中定义的 "token68" 语法。该值根据用户 ID 和密码计算,如下所述。

在收到对保护空间内缺少凭据的 URI 的请求后,服务器可以(can)使用 401(未授权)状态码([RFC7235],第 3.1 节)和 WWW-Authenticate 头字段([RFC7235],第 4.1 节)进行质询响应。

例如:

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

其中 "WallyWorld" 是服务器分配的用于标识保护空间的字符串。

代理可以使用 407(需要代理认证)状态码([RFC7235],第 3.2 节)和 Proxy-Authenticate 头字段([RFC7235],第 4.3 节)进行类似的质询响应。

要获得授权,客户端需要:

  1. 从用户获取用户 ID 和密码,
  2. 通过连接用户 ID、单个冒号(":")字符和密码来构造 user-pass,
  3. 将 user-pass 编码为八位字节序列(有关字符编码方案的讨论,请参见下文),
  4. 通过使用 Base64([RFC4648],第 4 节)将此八位字节序列编码为 US-ASCII 字符序列([RFC0020])来获取 basic-credentials。

此认证方案的原始定义未能指定用于将 user-pass 转换为八位字节序列的字符编码方案。在实践中,大多数实现选择了特定于语言环境的编码(如 ISO-8859-1,[ISO-8859-1])或 UTF-8([RFC3629])。出于向后兼容性的原因,只要与 US-ASCII 兼容(将任何 US-ASCII 字符映射到与 US-ASCII 字符代码匹配的单个八位字节),本规范继续保留默认编码未定义。

用户 ID 和密码禁止(MUST NOT)包含任何控制字符(参见 [RFC5234] 附录 B.1 中的 "CTL")。

此外,包含冒号字符的用户 ID 是无效的,因为 user-pass 字符串中的第一个冒号将用户 ID 和密码彼此分开;第一个冒号之后的文本是密码的一部分。包含冒号的用户 ID 无法在 user-pass 字符串中编码。

请注意,许多用户代理在生成 user-pass 字符串时不检查用户提供的用户 ID 是否不包含冒号;接收方将把用户名输入的一部分视为密码的一部分。

如果用户代理希望发送用户 ID "Aladdin" 和密码 "open sesame",它将使用以下头字段:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

2.1. 'charset' 认证参数

在质询中,服务器可以使用 'charset' 认证参数来指示它们期望用户代理在生成 "user-pass"(八位字节序列)时使用的字符编码方案。此信息纯粹是建议性的。

唯一允许的值是 "UTF-8";它应不区分大小写地匹配(参见 [RFC2978],第 2.3 节)。它表示服务器期望字符数据转换为 Unicode 规范化形式 C("NFC";参见 [RFC5198] 的第 3 节)并使用 UTF-8 字符编码方案([RFC3629])编码为八位字节。

对于用户 ID,接收方必须(MUST)支持 [RFC7613] 第 3.3 节中定义的 "UsernameCasePreserved" 配置文件中定义的所有字符,但冒号(":")字符除外。

对于密码,接收方必须(MUST)支持 [RFC7613] 第 4.2 节中定义的 "OpaqueString" 配置文件中定义的所有字符。

其他值保留供将来使用。

注意:'charset' 仅在质询中定义,因为 Basic 认证对凭据使用单个令牌('token68' 语法);因此,凭据语法不可扩展。

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

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

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

请注意,参数值可以是令牌或引号字符串;在这种情况下,服务器选择使用引号字符串表示法。

用户的名称是 "test",密码是字符串 "123" 后跟 Unicode 字符 U+00A3(英镑符号)。使用字符编码方案 UTF-8,user-pass 变为:

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

将此八位字节序列用 Base64([RFC4648],第 4 节)编码得到:

dGVzdDoxMjPCow==

因此,Authorization 头字段将是:

Authorization: Basic dGVzdDoxMjPCow==

或者,对于代理认证:

Proxy-Authorization: Basic dGVzdDoxMjPCow==

2.2. 重用凭据

给定已认证请求的绝对 URI([RFC3986],第 4.3 节),该请求的认证范围是通过删除路径组件("hier_part";参见 [RFC3986],第 3 节)中最后一个斜杠("/")字符之后的所有字符获得的。客户端应该(SHOULD)假设由具有认证范围前缀匹配的 URI 标识的资源也在该已认证请求的领域值指定的保护空间内。

客户端可以(MAY)主动发送相应的 Authorization 头字段,用于该空间中的资源请求,而无需从服务器接收另一个质询。类似地,当客户端向代理发送请求时,它可以(MAY)在 Proxy-Authorization 头字段中重用用户 ID 和密码,而无需从代理服务器接收另一个质询。

例如,给定一个已认证的请求:

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

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

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/

将被视为在认证范围之外。

请注意,URI 可以是多个认证范围的一部分(例如 "http://example.com/" 和 "http://example.com/docs/")。本规范未定义应该以更高优先级处理哪一个。