Posted on:
Last modified:
周末给一个库添加 http 代理的支持,发现对 http basic auth 不甚了解,阅读了一下相关的文档, 写篇备忘。
http 中的认证主要是 basic auth 和 digest auth 两种,其中 digest auth 比较复杂,而且也没有 提升安全性,已经不建议使用了。
RFC 7235 [1] 描述了客户端(通常是浏览器)和服务器如何通过 http 进行身份认证的一些机制。 客户端和 http 代理之间也可以使用 http auth 来做验证。
WWW-Authenticate
header,并指定验证的
type 和 realm,具体定义下文有讲。Authorization
header 发送验证的密钥。如果验证通过的话,应该正常访问(200 OK),
验证通过但是没有权限的话应该返回 403 Forbidden。注意,如果客户端已经知道需要密钥访问,那么可以在第一个请求直接发送对应的密钥,这样就避免了 401 Unauthorized。
如果代理服务器需要验证的话,流程是类似的,有两点细节不同:
服务器或者代理服务器随着 4XX 发送的头部为
WWW-Authenticate: <type> realm=<realm>
or
Proxy-Authenticate: <type> realm=<realm>
其中 type 指定了使用的验证的类型,也就是用户名和密码加密方式的不同,IANA 钦定了一批方法 [2]。然鹅,一般来说常用的只有两个 Basic 和 Digest。而其中 Digest 的实现可能会要求服务器 明文存储密码,于是大家又 angry 了 [3],这里也不推荐使用。所以这里只介绍 Basic 类型。
realm 指定了验证的领域,也就是说相同 realm 下的用户名和密码是一样的,如果你访问的两个页面 在同一个 realm,那么浏览器在第二次访问就不会问你密码了。
客户端发送对应的头部和密钥来获得访问权限
Authorization: <type> <credentials>
or
Proxy-Authorization: <type> <credentials>
其中,type 就是刚刚的那个 Basic 或者 Digest。credentials 按照对应的方法计算。对于 Basic
类型 credentials = base64(username + ':' + password)
一个例子,假设用户名和密码分别是:aladdin 和 opensesame。那么客户端应该发送的 header 是:
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
因为 http 协议本身是无状态的,所以 Auth 应该是无状态的,每次请求都应该携带。
如果是 http 协议的话,对于 Basic Auth,那么密码都是明文发送的,可以使用 https 来避免 这个问题。
可以使用:https://username:password@www.example.com/ 这种形式来预先输入账号密码,但是 这种形式已经不鼓励了。不过在设定一些环境变量时,比如 http_proxy,也只能用这种方法来制定 用户名和密码
© 2016-2022 Yifei Kong. Powered by ynotes
All contents are under the CC-BY-NC-SA license, if not otherwise specified.
Opinions expressed here are solely my own and do not express the views or opinions of my employer.
友情链接: MySQL 教程站