目录

  1. 概述
  2. HTTP 认证框架
  3. 认证协议与首部
  4. 安全域(Realm)
  5. 基本认证
    1. 基本认证实例
    2. Base-64 编码
    3. 基本认证的安全缺陷
  6. 代理认证
  7. 摘要认证

移动互联网的发展,通过 Web 可以方便地访问许多信息。但仅仅方便用户访问是不够的,还需要做到细粒度的用户认证

例如:某资源网站中,只有登录的用户才能够下载相关资源,没有登录的用户甚至看不到资源下载地址,这就是一种典型的细粒度用户认证案例。未授权用户无法查看其他用户的个人隐私数据,也不能在未经许可的情况下向 Web 站点发布文档。

本章将阐述 HTTP 的认证机制,深入介绍最常见的 HTTP 认证的两种形式:基本认证(basic authentication)以及摘要认证(digest authentication)

概述

❓什么是认证?

认证是一种验证身份的技术,通过这种技术服务器可以了解用户的身份,一旦服务器知道了用户身份,就可以判定用户可以访问的事务和资源了。通常是通过提供用户名和密码进行认证的。尽管可以在 HTTP 的认证形式和 cookie 基础之上运行自己的认证工具,但在很多情况下,HTTP 的原生认证功能就可以很好地满足要求

HTTP 认证框架

HTTP 提供了一个原生的质询 / 响应(challenge/response)框架,简化了对用户的认证过程

⛵认证逻辑

  • Web 应用程序收到一条 HTTP 请求报文时,服务器没有按照请求执行动作,而是以一个认证质询进行响应,要求用户提供一些保密信息来说明他是谁,从而对其进行质询
  • 用户再次发起请求时,要附上保密证书(用户名和密码)。如果证书不匹配,服务器 可以再次质询客户端,或产生一条错误信息。如果证书匹配,就可以正常完成请求了。

认证协议与首部

HTTP 通过一组可定制的控制首部,为不同的认证协议提供了一个可扩展的认证框架,下图列出的首部格式和内容会随认证协议的不同而发生变化。认证协议也是在 HTTP 认证首部中指定的

请求认证的四个步骤

步骤首部描述方法/状态
请求第一条请求没有认证信息,只是请求资源GET
质询WWW-Authenticate服务器用 401 状态拒绝了请求,说明需要用 户提供用户名和密码。 服务器上可能会分为不同的区域,每个区 域都有自己的密码,所以服务器会在 WWW-Authenticate首部对保护区域进行描述。 同样,认证算法也是在 WWW-Authenticate 首部中指定的401 Unauthorized
授权Authorization客户端重新发出请求,但这一次会附加一个 Authorization 首部,用来说明认证算法、 用户名和密码GET
成功Authentication-Info如 果 授 权 证 书 是 正 确 的, 服 务 器 就 会 将 文 档 返 回。 有 些 授 权 算 法 会 在 可 选 的 Authentication-Info 首部返回一些与授 权会话相关的附加信息200 OK

基本认证实例如下:

  1. 服务器对用户进行质询时,会返回一条 401 Unauthorized 响应,并在 WWW-Authenticate 首部说明如何以及在哪里进行认证
  2. 当客户端授权服务器继续处理时,会重新发送请求,但会在 Authorization 首部附上加密的密码和其他一些认证参数
  3. 授权请求成功完成时,服务器会返回一个正常的状态码(比如,200 OK);对高级认证算法来说,可能还会在 Authentication-Info 首部附加一些额外的信息

安全域(Realm)

❓ HTTP 是怎样允许服务器为不同的资源使用不同的访问权限的?

上图中,WWW-Authenticate 质询中包含了一个 realm 指令。Web 服务器会将受保护的文档组织成一个安全域(security realm),每个安全域都可以有不同的授权用户集

比如,假设 Web 服务器建立了两个安全域:一个用于公司的财务信息,另一个用于个人家庭文档。不同的用户对各个安全域的访问权限是不同的。 公司的 CEO 应该能够访问销售额预测资料,但不应该允许他访问员工和其家人度假的照片!

下面是一个假想的基本认证质询,它指定了一个域

1
2
HTTP/1.0 401 Unauthorized
WWW-Authenticate: Basic realm="Corporate Financials"

域(realm)应该有一个描述性的字符名,比如 Corporate Financials(公司财务资料),以帮助用户了解应该使用哪个用户名和密码。在安全域的名称中列出服务器主机名也是很有帮助的,比如:

1
2
HTTP/1.0 401 Unauthorized
WWW-Authenticate: Basic realm="executive-committee@bigcompany.com"

基本认证

基本认证是最流行的 HTTP 认证协议,几乎每个客户端和服务器都实现了基本认证机制。

  • 在基本认证中,Web 服务器可以拒绝一个事务,质询客户端,请用户提供有效的用户名和密码。此时服务器会返回 401 状态码,而不是 200 状态码来初始化认证质询,并用 WWW-Authenticate 响应首部指定要访问的安全域;
  • 浏览器收到质询时,会打开一个对话框,请求用户输入这个域的用户名和密码。然后将用户名和密码稍加扰码,再用 Authorization 请求首部回送给服务器

基本认证实例

下表总结了 HTTP 基本认证的 WWW-Authenticate 和 Authorization 首部

质询/响应首部语法及描述
质询(服务器发往客户端)网站的不同部分可能有不同的密码。realm 域就是一个引用字符串,用来命名所请求的文档集,这样用户就知道该使用哪个密码了WWW-Authenticate: Basic realm=quoted-realm
响应(客户端发往服务器)用冒号( :)将用户名和密码连接起来,然后转换成 Base-64 编码,这样能尽量避免攻击者通过观察网络流量并只进行一些粗略的检查就获取用户名和密码的情况发生: Authorization: Basic base64-username-and-password

🎶 基本认证协议并没有使用 Authentication-Info 首部

Base-64 编码

❓什么是 base64 编码

简单来说,Base-64 编码是一种编码格式,会将一个 8 位字节序列划分为一些 6 位的块。用每个 6 位的块在一个特殊的由 64 个字符组成的字母表中选择一个字符,这个字母表中包含了大部分字母和数字

Base-64 编码可以接受二进制字符串、文本、国际字符表示的数据,将其暂时转换成一个易移植的字母表以便传输。然后,在远端就可以解码出原始字符串,而无需担心传输错误了。

有些用户名和密码中会包含国际字符或其他在 HTTP 首部中非法的字符(比如引号、 冒号和回车换行符),对这些用户名和密码来说,Base-64 编码是非常有用的。而且,Base-64 编码扰乱了用户名和密码,这样也可以防止管理员在管理服务器和网络时,不小心看到用户名和密码

基本认证的安全缺陷

基本认证简单便捷,但并不安全。只能用它来防止非恶意用户无意间进行的访问,或将其与 SSL 这样的加密技术配合使用,总而言之,基本认证存在下列安全缺陷

基本认证会通过网络发送用户名和密码,这些用户名和密码都是以一种很容易解码的形式表示的。实际上,密码是以明文形式传输的,任何人都可以读取并将其捕获。虽然 Base-64 编码通过隐藏用户名和密码,致使一般用户不太可能在进行网络观测时无意中看到密码,但 Base-64 编码的用户名和密码可以很轻易地通过反向编码过程进行解码。所以经过 Base-64 编码的密码实际上就是明文传送的

即使密码是以更难解码的方式(非 base-64 编码)加密的,第三方用户仍然可以捕获被修改过的用户名和密码,并将修改过的用户名和密码一次一次地重放给原始服务器,以获得对服务器的访问权。没有什么措施可用来防止这些重放攻击

即使将基本认证用于一些不太重要的应用程序,比如公司内部网络的访问控制或个性化内容的访问,「 一些不良习惯 」也会让它变得很危险。很多用户由于受不了大量密码保护的服务,会在这些服务间使用相同的用户名和密码。比如说,某个狡猾的攻击者会从免费的因特网邮件网站捕获明文形式的用户名和密码,然后会发现用同样的用户名和密码还可以访问重要的在线银行网站!

基本认证没有提供任何针对代理和作为中间人的中间节点的防护措施,它们没有修改认证首部,但却修改了报文的其余部分,这样就严重地改变了事务的本质

假冒服务器很容易骗过基本认证,如果在用户实际连接到一台恶意服务器或网关的时候,能够让用户相信他连接的是一个受基本认证保护的合法主机,攻击者就可以请求用户输入密码,将其存储起来以备未来使用,然后捏造一条错误信息传送给用户。这就是典型的中间人攻击。

这一切说明,在隐私保护严格的环境中,可以通过基本认证来提供便捷的文档个性化服务或访问控制保护,但是并不能真正的保证安全。通过这种方式,只能防止一些好奇的用户无意中或不小心对文档进行访问,对于专业的攻击者还是能够通过不正当的手段进行访问

比如,在一个公司内部,产品管理可能要对未来的产品计划进行密码保护,以防止信息的过早发布。对一般用户而言,基本认证就足以让他们感到不便而不会再去访问这些数据了。同样,你可能会用密码来保护那些并非高度机密的,或者没什么信息价值的私人照片或私有站点,这些信息确实和其他人也没什么关系。将基本认证与加密数据传输(比如 SSL)配合使用,向恶意用户隐藏用户名和密码,会使基本认证变得更加安全,这是一种常用的技巧

🎶 如果一个场景中有第三方会去拦截基本认证发送的用户名和密码,就要通过 SSL 加密信道发送所有的 HTTP 事务,或者使用更安全的认证协议,比如摘要认证

代理认证

中间的代理服务器也可以实现认证功能。有些组织会在用户访问服务器、LAN 或无线网络之前,用代理服务器对其进行认证。可以在代理服务器上对访问策略进行集中管理,因此,通过代理服务器提供对某组织内部资源的统一访问控制是一种很便捷的方式。这个过程的第一步就是通过代理认证(proxy authentication)来识别身份。

代理认证的步骤与 Web 服务器身份验证的步骤相同。但首部和状态码都有所不同。 下表列出了 Web 服务器和代理在认证中使用的状态码和首部的差异

Web 服务器与代理认证的差异

Web 服务器代理服务器
Unauthorized status code: 401Unauthorized status code: 407
WWW-AuthenticateProxy-Authenticate
AuthorizationProxy-Authorization
Authentication-InfoProxy-Authentication-Info

摘要认证

基本认证便捷灵活,但极不安全,用户名和密码都是以明文形式传送的,用户名和密码用 Base-64 编码进行了加密,但很容易被解密。只能防止无意中的查看,没有任何防止恶意用户攻击的手段, 也没有采取任何措施防止对报文的篡改。安全使用基本认证的唯一方式就是将其与 SSL 配合使用

摘要认证与基本认证兼容,但却更为安全,尽管摘要认证还没有得到广泛应用,但对实现安全事务来说,这些概念是非常重要的,摘要认证是另一种 HTTP 认证协议,它试图修复基本认证协议的严重缺陷。具体来说,摘要认证进行了如下改进:

  • 永远不会以明文方式在网络上发送密码
  • 可以防止恶意用户捕获并重放认证的握手过程
  • 可以有选择地防止对报文内容的篡改
  • 防范其他几种常见的攻击方式

摘要认证并不是最安全的协议,与基于公有密钥的机制相比,摘要认证所提供的认证机制就不够强。同样,摘要认证除了能保护密码外,并没有提供保护其他内容的方式,请求和应答中的其余部分仍然可能被窃听;摘要认证并不能满足安全 HTTP 事务的很多需求,对这些需求来说,使用传输层安全(Transport Layer Security,TLS)和安全 HTTP (Secure HTTP,HTTPS)协议更为合适

但摘要认证比它要取代的基本认证强大很多。与很多建议其他因特网服务使用的常用策略相比,(比如曾建议 LDAP、POP 和 IMAP 使用的 CRAM-MD5),摘要认证也要强大很多