多个 HTTP 授权标头?

问题描述 投票:0回答:7

是否可以在 HTTP 消息中包含多个授权标头?具体来说,我想包括一种承载令牌类型(传递 OAuth 访问令牌)和一种基本类型(传递 base64 编码的用户名:密码)。

GET /presence/alice HTTP/1.1 
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM
Authorization: Basic YXNkZnNhZGZzYWRmOlZLdDVOMVhk

我认为没有理由这是不可能的,只是想与社区一起审查以确定。

http oauth authorization
7个回答
57
投票

**** 2021 年 2 月更新 *** 请阅读对此回复的评论。他们的总体结论似乎是某些 Web 服务器接受多种授权方案,但这违反了 RFC 7230/7235 ****

这应该是可能的,您只需在字段值之间添加逗号即可,例如:

GET /presence/alice HTTP/1.1 
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM, Basic YXNkZnNhZGZzYWRmOlZLdDVOMVhk

这在 RFC7230,第 3.2.2 节,字段顺序中定义:

发送方不得在消息中生成具有相同字段名称的多个标头字段,除非该标头字段的整个字段值被定义为逗号分隔列表[即#(values)]或者标头字段是一个井-已知异常(如下所述)。

接收者可以将具有相同字段名称的多个头字段组合成一个“字段名称:字段值”对,而不改变消息的语义,方法是将每个后续字段值按顺序附加到组合字段值上,用一个逗号。因此,具有相同字段名称的标头字段的接收顺序对于组合字段值的解释非常重要;代理在转发消息时不得更改这些字段值的顺序。

我不知道是否所有网络服务器都接受这一点 - 在撰写本文时,我正在与一位同事争论它是否应该起作用。


40
投票

不,这是不可能的。请参阅 http://greenbytes.de/tech/webdav/rfc7235.html#header.authorization

中的语法定义

11
投票

我也有类似的问题。这似乎是一个很常见的问题 (问题链接)。我最终将不记名令牌的授权标头更改为非标准标头,例如

X-Auth:承载 mF_9.B5f-4.1JqM

这样,它只是另一个 HTTP 标头,基本的 http 授权就会通过。如果您正在开发自己的 API,这应该没问题。

一些进一步的研究

基于 RFC 2617,这里有一些有趣的细节。

用户代理必须 选择使用具有最强身份验证方案的挑战之一 理解并据此向用户请求凭据 挑战。

请注意,许多浏览器只能识别 Basic,并且需要 这是第一个提出的授权方案。服务器应该只 如果最低限度可以接受,请包括基本的。


2
投票

如果你在后端使用 python,那么你可以简单地在 bearer 中传递 dict,然后在后端处理它之前执行 json.loads

通过这种方式,您可以在一个授权标头中传递多个值

示例:通过

{"access_token" : access_token, "app_id" : 2}

后端

json.loads("{"access_token" : access_token, "app_id" : 2}")


1
投票

标题字段是键/值对。因此,只要它们是独一无二的,并且您/程序员知道谁是谁,就可以了。例如:

AuthorizationBearer: Bearer mF_9.B5f-4.1JqM
AuthorizationBasic: Basic YXNkZnNhZGZzYWRmOlZLdDVOMVhk

当我的 Angular 拦截器将

Authorization111: Bearer xyz123
发送到 Node API 时,API 会将令牌值提取为

// you can do more validation here, i.e, length
var token = header.headers["authorization111"].toString().split(' ')[1];  

0
投票

虽然

Authorization
的逗号分隔值在技术上是最佳解决方案,但作为最后的立场,您可以尝试将普通用户凭据作为 URL 的一部分与您选择的 httpClient 一起添加,并使用它发送
Bearer
标头。如果没有其他办法的话可能会起作用:

https://myUsername:[email protected]/presence/alice

由于此处使用明文密码,这只是为了完整性,而不是推荐的方式。


-2
投票

有可能有多个授权标头,我在集成接受多个授权的API时遇到了同样的问题。

这里是 React js 示例,用于调用接受多个身份验证令牌的 API。

axios.get(Constants.API+Constants.GET_USER,  {  headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
"Authorization": Constants.AUTH_Element + ',' + Constants.AUTH_ORG + ','+ 
Constants.AUTH_USER
}})
.then(function (response) {
    // handle success
    console.log(response);
})
.catch(function (error) {
    // handle error
    console.log(error);
})
.finally(function () {
    // always executed
});
© www.soinside.com 2019 - 2024. All rights reserved.