以安全的方式重定向用户和数据
Redirecting users and data en a secure way
来自网站(外部网站)的用户需要重定向到我的网站。
与重定向一起,有关用户的数据将被传输,不应使用查询字符串发送。
但是,我不确定如何以安全的方式执行此操作,以确保重定向(和数据)实际上来自外部合作伙伴。
我最初的想法是创建一个 oauth 身份验证服务器,它将 return 到外部站点的令牌。如果提供了有效的用户名和密码,令牌将被 returned,并且仅在设定的时间内有效。
然后应使用令牌将数据从外部站点传输到我的 API/MVC 站点。然而,我仍然无法继续下去,因为我不认为网络服务器可以在重定向的同时传输身份验证令牌。
如何匹配重定向和数据,同时确保外部站点是可信赖的合作伙伴?
我会使用类似 OAuth 的方法。两台服务器都有一个共享的秘密(GUID 或其他)。呈现表单时,服务器 A 会生成一个随机的 "nonce" 令牌。它还获取时间戳(对于 OAuth,它是自 1/1/1970 以来的秒数)。您将 nonce、时间戳和共享机密字符串连接起来,然后对它们进行哈希处理(使用 SHA 或其他方法)。这个散列值称为签名。然后包括以下作为隐藏输入参数:
- 随机数
- 时间戳
- 签名
当服务器 B 收到响应时,它会做一些事情:
- 确保时间戳在服务器 B 时钟的 X 分钟内。
- 确保 nonce 没有被使用(我稍后会讨论)。
- 连接时间戳、随机数和服务器 B 的共享副本
秘密。使用相同的算法对它们进行哈希处理。
- 进行字符串比较
在 $POST['signature'] 上使用新生成的签名。如果
它们匹配然后你知道请求来自服务器 A.
Nonces 并不是普遍唯一的,它们仅在特定时间范围内是唯一的。为了跟踪它们,您必须在全局范围内保留字典。键是随机数,值是使用时的时间戳。当请求进来时,在字典中查找随机数。如果与其关联的时间戳在服务器 B 时钟的 +/-X 分钟内,则拒绝该请求。如果它在你的范围之外,或者它还不在字典中,那么允许请求并将随机数和时间戳添加到字典中。
重点是防止重放攻击。机器人无法嗅探流量,获取明显可见的随机数、时间戳和签名,并使用不同的有效负载再次将其发送到服务器 B。
关于时间戳范围(上面的 X)的注释,在 OAuth 中它有一个单一的目的:在服务器时钟的差异之间提供一个缓冲区。在这方面,它通常很短 -- 几分钟。在您的情况下,服务器 A 在初始页面加载时生成随机数,因此时间戳范围必须包括用户填写表单的时间。我建议时间戳不能比当前服务器时间早几分钟,但可以比服务器时间晚 30-60 分钟。缺点是您的 nonce 字典必须保留更长时间的值。
来自网站(外部网站)的用户需要重定向到我的网站。 与重定向一起,有关用户的数据将被传输,不应使用查询字符串发送。
但是,我不确定如何以安全的方式执行此操作,以确保重定向(和数据)实际上来自外部合作伙伴。
我最初的想法是创建一个 oauth 身份验证服务器,它将 return 到外部站点的令牌。如果提供了有效的用户名和密码,令牌将被 returned,并且仅在设定的时间内有效。
然后应使用令牌将数据从外部站点传输到我的 API/MVC 站点。然而,我仍然无法继续下去,因为我不认为网络服务器可以在重定向的同时传输身份验证令牌。
如何匹配重定向和数据,同时确保外部站点是可信赖的合作伙伴?
我会使用类似 OAuth 的方法。两台服务器都有一个共享的秘密(GUID 或其他)。呈现表单时,服务器 A 会生成一个随机的 "nonce" 令牌。它还获取时间戳(对于 OAuth,它是自 1/1/1970 以来的秒数)。您将 nonce、时间戳和共享机密字符串连接起来,然后对它们进行哈希处理(使用 SHA 或其他方法)。这个散列值称为签名。然后包括以下作为隐藏输入参数:
- 随机数
- 时间戳
- 签名
当服务器 B 收到响应时,它会做一些事情:
- 确保时间戳在服务器 B 时钟的 X 分钟内。
- 确保 nonce 没有被使用(我稍后会讨论)。
- 连接时间戳、随机数和服务器 B 的共享副本 秘密。使用相同的算法对它们进行哈希处理。
- 进行字符串比较 在 $POST['signature'] 上使用新生成的签名。如果 它们匹配然后你知道请求来自服务器 A.
Nonces 并不是普遍唯一的,它们仅在特定时间范围内是唯一的。为了跟踪它们,您必须在全局范围内保留字典。键是随机数,值是使用时的时间戳。当请求进来时,在字典中查找随机数。如果与其关联的时间戳在服务器 B 时钟的 +/-X 分钟内,则拒绝该请求。如果它在你的范围之外,或者它还不在字典中,那么允许请求并将随机数和时间戳添加到字典中。
重点是防止重放攻击。机器人无法嗅探流量,获取明显可见的随机数、时间戳和签名,并使用不同的有效负载再次将其发送到服务器 B。
关于时间戳范围(上面的 X)的注释,在 OAuth 中它有一个单一的目的:在服务器时钟的差异之间提供一个缓冲区。在这方面,它通常很短 -- 几分钟。在您的情况下,服务器 A 在初始页面加载时生成随机数,因此时间戳范围必须包括用户填写表单的时间。我建议时间戳不能比当前服务器时间早几分钟,但可以比服务器时间晚 30-60 分钟。缺点是您的 nonce 字典必须保留更长时间的值。