自定义授权标头
Posted
技术标签:
【中文标题】自定义授权标头【英文标题】:Custom Authorization Header 【发布时间】:2017-07-23 06:38:40 【问题描述】:我知道 Stack Overflow 上有足够的内容来回答这个问题,但我的主题与其他主题不同。 (有点相同但不相等)
我想听听社区对我所做的事情的看法,看看我是否可以在某些方面有所改进。
我目前正在为我的登录端点使用 BASIC 授权,因为它不需要复杂性并且它通过 https 所以它的方式很好。
示例:
GET - /api/login
授权:基本 BASE64String(用户名:密码)
我的一些 EndPoints 需要令牌才能被授予对资源的访问权限。我通过标头和 Https-Secured 发送这些令牌。
问题是我没有使用传统的方法来进行这些授权。下面是一些例子:
示例 1:
GET - /api/hardware/PUBLIC_TOKEN/getMe
授权-硬件:PRIVATE_TOKEN
此 EndPoint 不需要 Authorization-Hardware Header,但如果包含更多内容,则由 API 完成。 (这里不相关)
示例 2:
GET - /api/login/id
授权人:USER_TOKEN
否则,此端点是必要的,包括带有用户令牌的 Authorization-Person 标头来访问资源。 (注意这里不讲Token是如何产生的)
要访问 API 端点,需要 HTTPS 请求。
我为上面的自定义标头和端点指定了任意名称,只是为了说明我的授权架构是什么,名称与原始名称不匹配。所以不要打扰那些只关注架构的名称。
我的问题是:不遵循传统的方式是一件坏事吗?创建在某种程度上是不好的(如果是为什么?)。
我发现这种方式更容易给予授权和传递令牌的安全方式,所有这些令牌都可以再次在平台中重新生成。
许多设备和移动应用程序已经在使用此架构,但它都在开发环境中,尚未投入生产。我担心这种非常规的做法会在未来影响 API 的用户。希望社区的想法可以帮助我改进这一点。
编辑:26/03/2017
我想知道它是否会更好以及为什么以协议中描述的方式实现,因为当需要多个授权时比您拥有自定义标头并想要检索时更难从标头中获取它的价值。
按照协议,您应该像这样使用授权标头:
Authorization: <type> <value>
示例:
GET - /api/login/id
授权:用户USER_TOKEN
但我只是看不到我在此之后获得了什么,因为在获取它的值时会出现一个字符串,或者在示例情况下它会返回用户令牌。
使用自定义标头可以更轻松地验证令牌。遵循协议方式的多重授权也会让人头疼。
【问题讨论】:
我真的需要一些帮助我越来越接近完成产品! 【参考方案1】:TL;DR 某些标头名称(例如 Authorization
)具有关于缓存以及代理和客户端处理的特殊规则;除非您修改了每个代理和客户端,否则您的自定义标头名称不会获得特殊行为。
使用RFC7234 中定义的通用Authorization: <type> <value>
标头主要是为了确保本机实现对这些标头的处理的客户端和HTTP 代理行为正确。
RFC7234 第 4.2 节说:
转发请求的代理不得修改任何授权字段 在那个请求中。请参阅 [RFC7234] 的第 3.2 节了解详细信息和 与处理授权字段有关的要求 HTTP 缓存。
代理可能修改、省略、记录或缓存您的其他 Authorization-*
标头。
RFC7234, section 3.2 表示请求/响应 Authorization
标头不得缓存(特定情况除外)。
RFC7235, section 5.1.2, point 7 还对使用Authorization
以外的标头的新身份验证方案有这样的看法:
因此,选择不在授权头字段中携带凭据的新身份验证方案(例如,使用新定义的头字段)将需要通过强制使用任一 Cache-Control 请求指令(例如, “no-store”,[RFC7234] 的第 5.2.1.5 节)或响应指令(例如,“private”)。
那么你应该怎么做...?如果您完全控制系统的两端,那么定义一个可能具有多个参数以涵盖一种或多种令牌类型的任意组合的新类型值并非不合理,只需避免,
字符:
Authorization: MyAuth User=USER_TOKEN/Hardware=HWTOKEN/Person=PERSONTOKEN/Basic=...
替代方案更多地取决于服务器和客户端实现,并且将使用,
作为多个标头的替代版本列表形式:
Authorization: User USER_TOKEN, Hardware=HWTOKEN, Person=PERSONTOKEN, Basic=...
取决于服务器和客户端,可能被视为相同:
Authorization: User USER_TOKEN
Authorization: Hardware HWTOKEN
Authorization: Person PERSONTOKEN
Authorization: Basic ...
这里的问题是“可以”(很多额外的强调)被同等对待。有讨论表明,各种版本的 Apache 和 nginx 并没有一致地处理这一点,并且旧的 HTTP RFC 对预期行为非常不清楚。
【讨论】:
这对这个主题很有启发!谢谢 !我仍在决定应该使用什么,但我会尽量避免使用自定义名称标题。 检查tools.ietf.org/html/rfc7230#section-3.2.2,它说“发件人不得在消息中生成多个具有相同字段名称的头字段,除非该头字段的整个字段值被定义为逗号分隔的列表[即,#(values)] 或标头字段是众所周知的例外(如下所述)。" 另外," 接收者可以通过附加每个后续字段值,将具有相同字段名称的多个标题字段组合成一个“字段名称:字段值”对,而不改变消息的语义到组合字段值的顺序,用逗号分隔。因此,接收具有相同字段名称的头字段的顺序对组合字段值的解释很重要;代理不得更改这些字段值的顺序转发消息。”话虽如此,带有 , 的多重授权模式似乎是有效的,但不适用于后者。以上是关于自定义授权标头的主要内容,如果未能解决你的问题,请参考以下文章
ORBEON:是不是可以添加自定义标头或向 API 授权方发送会话 cookie
如何在自定义授权方 AWS lambda 函数中访问 http 标头
如何使用带有 WebClient 的 spring-security-oauth2 自定义 OAuth2 令牌请求的授权标头?