VPN 内的 OAuth:哪些环节仍然需要 TLS
VPN 改变的是谁能到达服务器,而不是 OAuth 报文如何传输。按环节判断:授权响应、令牌请求和 bearer 调用。
私有路由决定谁能到达服务器;OAuth 的传输规则决定每条报文如何传输。浏览器、授权服务器、令牌端点和资源服务器可以全都位于同一个 VPN 之后,却仍然通过不同的环节交换报文。每个环节都有自己的传输要求,VPN 不会放宽其中任何一条。VPN 边界和协议边界是两条不同的界线。
如果你不再追问网络是否可信,而是开始追问哪次交换正在跨越哪条边界,决定就会容易得多。
按环节判断,而不是按网络判断
把各个端点分别写下来:授权端点、令牌端点、重定向 URI、资源服务器 URL、TLS 终止点和 VPN 网关。然后标出每一方发起哪个请求,以及响应去往哪里。
在网关处终止的 VPN 会加密到该网关的这一段。请求在其后仍可能以明文 HTTP 继续,而剩下的这一段并不会因为前一段被加密就变成 HTTPS。协议在意的正是这段延续。加密第一跳并不能让第二跳变得安全。
传输还承载服务身份校验。浏览器会校验应用 URL 的证书;VPN 不会代浏览器执行这项校验,也不会让未经校验的端点变得可接受。证书指明客户端认为自己正在调用的端点。通往网关的隧道不会重命名该端点,也不会校验它。
授权响应与重定向 URI
OAuth 当前的安全最佳实践禁止通过未加密连接传输授权响应。这不仅包括最初的请求,也包括把授权码或令牌带回客户端的重定向。
同一份指南不允许 HTTP 重定向 URI,指定的原生客户端回环情形除外。内部主机名不会创造新的例外;如果一个 DNS 名称只在 VPN 内部解析,只要 scheme 写的是 HTTP,它仍然是 HTTP URL。要检查注册 URI 中的 scheme,而不只是主机名。
把精确的 HTTPS 重定向 URI 注册到授权服务器,并在客户端保持证书校验开启。一个压制 HTTPS 要求的开发捷径,会产生与其本应模拟的生产配置行为不同的流程。
令牌端点与 bearer 令牌请求
令牌请求携带凭据或可换取访问权限的授权码。通过未受保护的环节发送它,会暴露资源服务器日后将要信任的材料,即使周边网络是私有的。能读取请求的代理也能读取它携带的凭据。
对于 bearer 令牌的资源请求,RFC 6750 把 TLS 视为该规范必须实现并使用的强制要求。把办公子网称为可信,并不是明文 bearer 部署所需要的那条通用协议例外。
两条环节都使用文档中给出的安全端点 URL。如果某个库拒绝调用 HTTP 令牌端点,这种拒绝正说明规范在起作用,而不是一个需要绕过的配置错误。把该 URL 记录在客户端配置中,而不是在运行时推导。
TLS 在哪里终止,又留下了什么
如果 TLS 在某个受信任的前端终止,就明确写出该前端,并审查从它到应用之间的路径。前端要对剩余段上的转发、信任和机密性负责,而该服务受支持的架构应当描述这种安排。
路径上其他位置的 VPN 并不能解决这些责任划分。它也无法告诉你,浏览器看到的应用 URL 是否与前端出示的证书相匹配。
对于内部部署,记录终止点以及它出示的身份。前端若用另一个名称的证书来终止 TLS,就会产生浏览器警告,而运维人员往往选择压制它,而不是修复它。
原生回环例外范围很窄
回环重定向例外针对的是用户自己设备上的回调,此时客户端和浏览器共用该设备。这种安排属于单台设备上的回调,并不授权通过 HTTP 向办公子网提供普通授权服务器或携带令牌的 API。
把例外限制在它所描述的客户端类型和回调范围内。把它套用到 Web 应用、共享内部服务或另一台主机上的重定向 URI,改变的是部署,而不是例外。
在每个边界上测试真实的流程,并与客户端类型对照。一个能用的重定向并不能说明每个携带令牌的环节都使用了所要求的保护;一个绿色的 VPN 图标也不能说明下一个请求的 scheme。