[身份认证/JWT] 身份认证方案与HTTP请求中Authorization Header

1 Authorization Header

1.0 背景引入

设计 API 授权,或者调用第三方 API 时,经常会接触到:

Authorization : Bearer {Token}

有没有疑惑为何不直接写成这样就得了:

Authorization : {Token}

1.1 HTTP 访问认证与Authorization 的格式 ∈ W3C的 HTTP 1.0 规范

这是因为 W3C 的 HTTP 1.0 规范,Authorization 的格式是:

Authorization: <type> <authorization-parameters>

所以 Bearer 是授权的类型,常见的授权类型还有:

  • Basic :用于 http-basic 认证;

  • Bearer :常见于 OAuth 和 JWT 授权;

  • Digest MD5 :哈希的 http-basic 认证 (已弃用)

  • AWS4-HMAC-SHA256 AWS 授权

  • ...

  • 我们一起来阅读一下规范原文:11. Access Authentication 章节

https://www.w3.org/Protocols/HTTP/1.0/spec.html#AA

11. 访问认证 - W3C HTTP 1.0 Protocol

11. Access Authentication / 11. 访问认证
	注: Authentication v. 鉴定;证明……是真实的;(用户,程序)验证身份

HTTP provides a simple challenge-response authentication mechanism which may be used by a server to challenge a client request and by a client to provide authentication information. It uses an extensible, case-insensitive token to identify the authentication scheme, followed by a comma-separated list of attribute-value pairs which carry the parameters necessary for achieving authentication via that scheme. HTTP提供了一种简单的 challenge-response 身份验证机制,服务器可以使用它来质疑客户端请求,客户端可以使用它来提供身份验证信息。它使用一个可扩展的、不区分大小写的令牌来标识身份验证方案,后面是一个逗号分隔的属性值对列表,其中包含通过该方案实现身份验证所需的参数。
       auth-scheme    = token 
       auth-param     = token "=" quoted-string
The 401 (unauthorized) response message is used by an origin server to challenge the authorization of a user agent. This response must include a WWW-Authenticate header field containing at least one challenge applicable to the requested resource. 401(未授权)响应消息由源服务器用来 challenge 用户代理的授权。此响应必须包括一个WWW-Authenticate报头字段,其中至少包含一个适用于所请求资源的 challenge 。
       challenge      = auth-scheme 1*SP realm *( "," auth-param )
       realm          = "realm" "=" realm-value
	     注:realm = 領域、范围
       realm-value    = quoted-string
The realm attribute (case-insensitive) is required for all authentication schemes which issue a challenge. The realm value (case-sensitive), in combination with the canonical root URL of the server being accessed, defines the protection space. These realms allow the protected resources on a server to be partitioned into a set of protection spaces, each with its own authentication scheme and/or authorization database. The realm value is a string, generally assigned by the origin server, which may have additional semantics specific to the authentication scheme. 所有发出质询的身份验证方案都需要realm属性(不区分大小写)。领域值(realm-value)(区分大小写)与正在访问的服务器的规范根URL结合在一起,定义了保护空间。这些领域(realm)允许将服务器上受保护的资源划分为一组保护空间,每个空间都有自己的身份验证方案和/或授权数据库。领域值(realm-value)是一个字符串,通常由源服务器分配,它可能具有特定于身份验证方案的附加语义。
A user agent that wishes to authenticate itself with a server--usually, but not necessarily, after receiving a 401 response--may do so by including an Authorization header field with the request. The Authorization field value consists of credentials containing the authentication information of the user agent for the realm of the resource being requested. 希望通过服务器对自己进行身份验证的用户代理(通常是在收到401响应之后,但不一定是这样)可以通过在请求中包含Authorization头字段来实现。Authorization字段值由凭据组成,凭据包含被请求资源领域的用户代理的身份验证信息。

       credentials    = basic-credentials
                      | ( auth-scheme #auth-param )
			注: credentials 即 凭证
The domain over which credentials can be automatically applied by a user agent is determined by the protection space. If a prior request has been authorized, the same credentials may be reused for all other requests within that protection space for a period of time determined by the authentication scheme, parameters, and/or user preference. Unless otherwise defined by the authentication scheme, a single protection space cannot extend outside the scope of its server. 用户代理可以自动应用凭据的域由保护空间决定。如果先前的请求已被授权,则在由身份验证方案、参数和/或用户首选项确定的一段时间内,可以为该保护空间内的所有其他请求重用相同的凭据(credentials)。除非认证方案另有定义,否则单个保护空间不能扩展到其服务器的范围之外。

If the server does not wish to accept the credentials sent with a request, it should return a 403 (forbidden) response.
如果服务器不希望接受与请求一起发送的凭据,它应该返回一个403(禁止)响应。


The HTTP protocol does not restrict applications to this simple challenge-response mechanism for access authentication. Additional mechanisms may be used, such as encryption at the transport level or via message encapsulation, and with additional header fields specifying authentication information. However, these additional mechanisms are not defined by this specification.
HTTP协议不限制应用程序使用这种简单的质询-响应机制进行访问身份验证。可以使用其他机制,例如在传输级别或通过消息封装进行加密,并使用指定身份验证信息的附加报头字段。然而,这些额外的机制并没有在本规范中定义。

Proxies must be completely transparent regarding user agent authentication. That is, they must forward the WWW-Authenticate and Authorization headers untouched, and must not cache the response to a request containing Authorization. HTTP/1.0 does not provide a means for a client to be authenticated with a proxy.

对于用户代理身份验证,代理必须完全透明。也就是说,它们必须原封不动地转发WWW-Authenticate和Authorization报头,并且不能缓存对包含Authorization的请求的响应。HTTP/1.0没有为客户端提供使用代理进行身份验证的方法。

11.1 基本认证方案 - W3C HTTP 1.0 Protocol

11.1 Basic Authentication Scheme 11.1 基本认证方案

The "basic" authentication scheme is based on the model that the user agent must authenticate itself with a user-ID and a password for each realm. The realm value should be considered an opaque string which can only be compared for equality with other realms on that server. The server will authorize the request only if it can validate the user-ID and password for the protection space of the Request-URI. There are no optional authentication parameters.
“基本”身份验证方案基于这样的模型:用户代理必须使用每个领域(realm)的用户id和密码对自己进行身份验证。领域值(realmValue)应该被认为是一个不透明的字符串,它只能与该服务器上的其他领域(realm)进行相等比较。只有当服务器能够验证请求uri的保护空间的用户id和密码时,服务器才会授权请求。没有可选的认证参数。

Upon receipt of an unauthorized request for a URI within the protection space, the server should respond with a challenge like the following:
在收到对保护空间内的URI的未经授权的请求时,服务器应该响应如下挑战:

       WWW-Authenticate: Basic realm="WallyWorld"

where "WallyWorld" is the string assigned by the server to identify the protection space of the Request-URI.
其中“WallyWorld”是服务器分配的字符串,用于标识请求uri的保护空间。

To receive authorization, the client sends the user-ID and password, separated by a single colon (":") character, within a base64 [5] encoded string in the credentials.
为了接收授权,客户端在凭证(credentials)中的base64[5]编码字符串中发送用户id和密码,用单个冒号(":")字符分隔。

       basic-credentials = "Basic" SP basic-cookie
       basic-cookie      = <base64 [5] encoding of userid-password,
                            except not limited to 76 char/line>
       userid-password   = [ token ] ":" *TEXT
	  
If the user agent wishes to send the user-ID "Aladdin" and password "open sesame", it would use the following header field:
如果用户代理希望发送用户id“Aladdin”和密码“open sesame”,它将使用以下头字段:

       Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

The basic authentication scheme is a non-secure method of filtering unauthorized access to resources on an HTTP server. It is based on the assumption that the connection between the client and the server can be regarded as a trusted carrier. As this is not generally true on an open network, the basic authentication scheme should be used accordingly. In spite of this, clients should implement the scheme in order to communicate with servers that use it.
基本身份验证方案是一种过滤对HTTP服务器上资源的未经授权访问的非安全方法。它基于客户端和服务器之间的连接可以被视为可信载体的假设。由于这在【开放网络】中通常不成立,因此应该相应地使用基本身份验证方案。尽管如此,客户端应该实现该方案,以便与使用该方案的服务器通信。

1.2 HTTP 认证 ∈ Mozilla 规范

  • HTTP 提供了访问控制身份验证的【通用框架】。本页介绍了用于身份验证的 HTTP 框架,并展示了如何使用 HTTP "basic" 方案来限制对服务器的访问。

通用HTTP认证框架

  • RFC 7235定义了 HTTP 身份验证框架,服务器可以使用该框架来质询客户端请求,客户端可以使用该框架来提供身份验证信息。

  • Challenge和Response流程如下:

  • 服务器以401(未授权)响应状态响应客户端,并提供有关如何使用WWW-Authenticate包含至少一个质询的响应标头进行授权的信息。
  • 然后,想要向服务器验证自身身份的客户端可以通过Authorization在凭据中包含请求header来实现此目的。
  • 通常,客户端会先向用户显示密码提示;然后,发出包含正确Authorization标头的请求。

对于大多数(如果不是全部)身份验证方案, 上面的一般消息流是相同的。标头中的实际信息及其编码方式确实发生了变化!
【警告】:上图中使用的“basic”身份验证方案发送已编码但未加密的凭据。除非通过安全连接(HTTPS/TLS)进行交换,否则这是完全不安全的。

Proxy authentication/代理认证

同样的质询和响应机制也可以用于代理身份验证。由于资源身份验证和代理身份验证可以共存,因此需要一组不同的标头和状态码。在代理的情况下,质疑状态码是407 (Proxy Authentication Required), Proxy-Authenticate响应头至少包含一个适用于代理的Challenge,Proxy-Authorization请求头用于向代理服务器提供凭据(credentials)。

Access forbidden/访问拒绝

  • If a (proxy) server receives invalid credentials, it should respond with a 401 Unauthorized or with a 407 Proxy Authentication Required, and the user may send a new request or replace the Authorization header field. 如果(代理)服务器接收到无效的凭据,它应该响应401 Unauthorized或407 proxy Authentication Required,用户可以发送一个新的请求或替换Authorization报头字段。

  • If a (proxy) server receives valid credentials that are inadequate to access a given resource, the server should respond with the 403 Forbidden status code. Unlike 401 Unauthorized or 407 Proxy Authentication Required, authentication is impossible for this user and browsers will not propose a new attempt. 如果(代理)服务器接收到的有效凭据不足以访问给定资源,服务器应该响应403 Forbidden状态码。与401未授权或407需要代理身份验证不同,此用户无法进行身份验证,浏览器不会提出新的尝试。

  • In all cases, the server may prefer returning a 404 Not Found status code, to hide the existence of the page to a user without adequate privileges or not correctly authenticated.在所有情况下,服务器可能更倾向于返回404 Not Found状态码,以向没有足够权限或没有正确身份验证的用户隐藏页面的存在。

WWW-Authenticate 和 Proxy-Authenticate Header

  • WWW-Authenticate和响应Proxy-Authenticate Header定义用于获取资源访问权限的身份验证方法。他们必须指定使用哪种身份验证方案,以便希望授权的客户端知道如何提供凭据。

  • 这些Header的语法如下:

WWW-Authenticate: <type> realm=<realm>
Proxy-Authenticate: <type> realm=<realm>

这里:

  • <type>身份验证方案(“Basic”是最常见的方案,下面介绍)。
  • realm/领域用于描述保护区或表示保护范围。这可以是诸如“访问临时站点”或类似的消息,以便用户知道他们正在尝试访问哪个空间。

授权和代理授权标头

和请求Header包含用于通过(代理)服务器验证用户代理AuthorizationProxy-Authorization凭据。这里,<type>再次需要 后面跟着凭证(credentials),凭证(credentials)可以根据使用的身份验证方案进行编码或加密。

Authorization: <type> <credentials>
Proxy-Authorization: <type> <credentials>

Authentication schemes/认证方案

  • 通用 HTTP 身份验证框架是许多身份验证方案的基础。
  • IANA 维护着一份身份验证方案列表,但主机服务(例如 Amazon AWS)还提供其他方案。

一些常见的身份验证方案包括:

  • Basic

请参阅RFC 7617,base64 编码的凭据。更多信息如下。

  • Bearer

请参阅RFC 6750,用于访问 OAuth 2.0 保护资源的不记名令牌

https://www.rfc-editor.org/rfc/rfc6750.html

  • Digest

请参阅RFC 7616。 Firefox 93 及更高版本支持 SHA-256 算法。以前的版本仅支持 MD5 哈希(不推荐)。

  • HOBA

请参阅RFC 7486,第 3 节,H TTP原始绑定身份验证,基于数字签名

  • Mutual

参见RFC 8120

  • Negotiate / NTLM

参见RFC4599

  • VAPID

参见RFC 7804

  • SCRAM

参见RFC 7804

  • AWS4-HMAC-SHA256

请参阅AWS 文档。该方案用于AWS3服务器身份验证。

各方案的安全强度及其在客户端或服务器软件中的可用性可能有所不同。

“basic”身份验证方案的【安全性】非常差,但受到广泛支持并且易于设置。下面对其进行更详细的介绍。

Basic authentication scheme/"Basic"身份认证方案

  • RFC 7617中定义了“Basic”HTTP 身份验证方案,该方案以用户ID密码对的形式传输凭证(credential),并使用 base64 进行编码。

Basic认证的安全性

  • 由于用户ID密码以【明文形式】在网络上传递(它是base64编码的,但base64是可逆编码),因此Basic身份验证方案并不安全。
  • HTTPS/TLS 应与Basic身份验证一起使用。如果没有这些额外的安全增强功能,则:不应使用基本身份验证来保护敏感或有价值的信息。

使用 Apache Server 和基本身份验证限制访问

  • 要使用密码保护 Apache 服务器上的目录,您将需要一个.htaccess和一个.htpasswd文件。

  • .htaccess文件通常如下所示:

AuthType Basic
AuthName "Access to the staging site"
AuthUserFile /path/to/.htpasswd
Require valid-user

.htaccess文件引用一个.htpasswd文件,其中每行包含一个用户名和一个密码,并用冒号 ( :) 分隔。您无法看到实际的密码,因为它们经过哈希处理(在本例中使用基于 MD5 的哈希处理)。请注意,如果您愿意,您可以对.htpasswd文件进行不同的命名,但请记住,任何人都不应访问此文件。 (Apache 通常配置为阻止访问.ht*文件)。

aladdin:$apr1$ZjTqBB3f$IF9gdYAGlMrs2fuINjHsz.
user2:$apr1$O04r.y2H$/vEkesPhVInBByJUkXitA/

使用 Nginx 和基本身份验证限制访问

  • 对于 Nginx,您需要指定要保护的位置以及auth_basic密码保护区域提供名称的指令。然后该auth_basic_user_file指令指向一个.htpasswd包含加密用户凭据的文件,就像上面的 Apache 示例一样。
location /status {
    auth_basic           "Access to the staging site";
    auth_basic_user_file /etc/apache2/.htpasswd;
}

使用 URL 中的凭据进行访问

  • 许多客户端还允许您使用包含用户名和密码的编码 URL 来避免登录提示,如下所示:
https://username:password@www.example.com/
  • 不推荐使用这些 URL
  • Chrome 中,出于安全原因,username:password@URL 中的部分会从子资源 URL 中删除。
  • Firefox 中,它会检查该网站是否确实需要身份验证,如果不需要,Firefox 将警告用户并提示“您即将www.example.com使用用户名登录该网站username,但该网站不需要身份验证。这可能是一个错误”。试图欺骗你。”如果该网站确实需要身份验证,Firefox 仍会要求用户确认“您将www.example.com使用用户名登录该网站username”。在将凭据发送到站点之前。请注意,Firefox 在显示提示以确定站点是否需要身份验证之前,在这两种情况下都会发送不带凭据的请求。

还可看看的其他身份认证方案(除Basic外)

1.3 Authorization Bearer 身份认证方案 : RFC6750 (The OAuth 2.0 Authorization Framework: Bearer Token Usage/OAuth 2.0授权框架:承载令牌的使用)

提案出处: https://www.rfc-editor.org/rfc/rfc6750.html

Abstract/摘要

  • This specification describes how to use bearer tokens in HTTP requests to access OAuth 2.0 protected resources. Any party in possession of a bearer token (a "bearer") can use it to get access to the associated resources (without demonstrating possession of a cryptographic key). To prevent misuse, bearer tokens need to be protected from disclosure in storage and in transport.

该规范描述了如何在HTTP请求中使用Bearer Token(别称:不记名Token、承载者Token)来访问受OAuth 2.0保护的资源。拥有Bearer Token的任何一方(“Bearer”)都可以使用它来访问相关资源(无需证明拥有加密密钥)。为了防止误用,Bearer Tokens需要在存储和运输过程中得到保护,以免泄露。

Overview/概述

  • OAuth provides a method for clients to access a protected resource on behalf of a resource owner. In the general case, before a client can access a protected resource, it must first obtain an authorization grant from the resource owner and then exchange the authorization grant for an access token. The access token represents the grant's scope, duration, and other attributes granted by the authorization grant. The client accesses the protected resource by presenting the access token to the resource server. In some cases, a client can directly present its own credentials to an authorization server to obtain an access token without having to first obtain an authorization grant from a resource owner.

OAuth为客户端提供了一种访问受保护资源的方法代表资源所有者。一般情况下,在客户可以访问受保护的资源,必须先获得授权授予(authorization grant),然后交换【授权授予】访问令牌(access token)访问令牌(Access Token)表示授权的范围、持续时间和授权授予的其他属性。客户端访问受保护的资源资源服务器的访问令牌(Access Token)。在某些情况下,客户端可以直接将自己的凭据(credentials)呈现给授权服务器(authorization server)以获取访问令牌(Access Token),而不必首先获取资源所有者授予的授权(authorization grant)。

  • The access token provides an abstraction, replacing different authorization constructs (e.g., username and password, assertion) for a single token understood by the resource server. This abstraction enables issuing access tokens valid for a short time period, as well as removing the resource server's need to understand a wide range of authentication schemes.

访问令牌(Access Token)提供了一个抽象,取代了不同的的授权结构(例如,用户名和密码、断言)资源服务器可以理解的单个令牌(a Token)。这种抽象还支持发出在短时间内有效的访问令牌作为移除资源服务器的需要,是一种易于理解的、应用范围很广身份验证方案


     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

Figure 1: Abstract Protocol Flow(图1: 抽象的协议流)

  • The abstract OAuth 2.0 flow illustrated in Figure 1 describes the interaction between the client, resource owner, authorization server, and resource server (described in [RFC6749]). The following two steps are specified within this document: (E) The client requests the protected resource from the resource server and authenticates by presenting the access token. (F) The resource server validates the access token, and if valid, serves the request. This document also imposes semantic requirements upon the access token returned in step (D).

图1所示的抽象OAuth 2.0流程描述了客户端资源所有者授权服务器资源服务器之间的交互(在RFC6749中描述)。本文档中指定了以下两个步骤:

  • (E)客户端向资源服务器请求受保护的资源,并通过提供访问令牌进行身份验证。
  • (F)资源服务器验证访问令牌,如果有效,则服务请求。该文档还对步骤(D)返回的访问令牌施加语义要求。

XXXX

Authorization {schema} :

  • Bearer代表Authorization头定义的schema

https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_scheme

1.2 JWT 官方的推荐格式 : Authorization: Bearer

1.3 Authorization: Bearer 的原理

  • "Authorization: Bearer" 是一种在 HTTP 请求头部中用于传递访问令牌(Access Token)的常见格式。它用于在客户端和服务器之间进行身份验证和授权操作。

底层原理是这样的:当客户端发送 HTTP 请求时,可以在请求头部中添加 "Authorization" 字段来传递访问令牌。"Bearer" 是其中一种认证方案(authentication scheme)的名称,用于指示后面的令牌是访问令牌

例如,如果你有一个名为 "access_token" 的访问令牌,你可以通过设置请求头部的 "Authorization" 字段来传递它:

Authorization: Bearer {access_token}
  • 服务器在接收到请求时,可以读取 "Authorization" 字段,并解析出令牌部分,即 "access_token"。然后,服务器可以使用该令牌进行身份验证和授权操作。

  • 使用 "Authorization: Bearer" 的形式可以带来一些好处:

  • 一致性:它遵循了 HTTP 规范中关于认证方案的标准格式,使得在不同的系统和框架之间可以更好地进行互操作性。
  • 可扩展性:"Bearer" 方案可以与不同类型的令牌一起使用,如基于 JSON Web Token (JWT) 的令牌,OAuth 2.0 的访问令牌等。
  • 安全性:通过将访问令牌放置在请求头部中,可以避免令牌泄露在 URL 参数或请求主体中的潜在风险。

需要注意的是,"Bearer" 方案本身并不提供加密或验证令牌的机制,它只是一种用于标识令牌类型的约定。实际的令牌验证和授权逻辑需要在服务器端进行,根据具体的身份验证和授权方案进行处理。

  • 总结来说,"Authorization: Bearer" 是一种在 HTTP 请求头部中用于传递访问令牌的格式。它指示后面的令牌是访问令牌,服务器可以读取并使用该令牌进行身份验证和授权操作。它提供了一种标准化和可扩展的方式来传递访问令牌,并提高了安全性和互操作性。

X 参考文献

  • Mozilla
posted @ 2024-04-17 22:36  千千寰宇  阅读(2660)  评论(0编辑  收藏  举报