【问题标题】:When to randomize auth code/state in oauth2?何时在 oauth2 中随机化身份验证代码/状态?
【发布时间】:2016-02-22 15:59:40
【问题描述】:

根据https://www.godoc.org/golang.org/x/oauth2#Config.AuthCodeURL的文档

...State 是保护用户免受 CSRF 攻击的令牌。您必须始终提供非零字符串...

https://www.rfc-editor.org/rfc/rfc6749#section-10.12

...发送到重定向 URI 端点以包含绑定请求的值的任何请求...

然而,这特别是在没有会话数据时的流程部分,即用户尚未登录并且仅在显示匿名页面时生成验证码。

那么如何在回调时随机化和比较这个值呢?它是每个服务器随机的静态值吗?

【问题讨论】:

    标签: go oauth-2.0


    【解决方案1】:

    状态

    推荐。客户端用来维护的不透明值 请求和回调之间的状态。授权 服务器在重定向用户代理时包含此值 给客户。该参数应该用于防止 如第 10.12 节所述的跨站点请求伪造。

    RFC 6749

    您使用state 来识别来自授权服务器的回调与发送的请求匹配。如果没有state,攻击者可以使用您未请求的随机访问令牌调用您的回调 url。使用state,您知道被调用的回调是对您提出的请求的响应。

    因此,您将每个发送的请求随机化 state 并跟踪它,直到您收到匹配的回调。只要猜不到就可以是你想要的任何东西。

    一种简单的方法是利用rand.Reader 和base64 编码结果:

    func state(n int) (string, error) {
        data := make([]byte, n)
        if _, err := io.ReadFull(rand.Reader, data); err != nil {
            return "", err
        }
        return base64.StdEncoding.EncodeToString(data), nil
    }
    

    【讨论】:

    • 我感到困惑的是“跟踪它直到...”部分。假设可能有多个同时请求,不能真正将其设置为全局变量。您是否建议从数据库行或其他内容中添加/删除?
    • 您可以使用map[string]user.Identifier 来存储每个请求的状态以及用户标识符:m[state] = userId。当回调到达时,在您的地图中查找用户标识符并将接收到的访问令牌与其关联。然后从地图中删除密钥。您可能希望使用某种形式的过期缓存来删除一段时间未回调的状态。
    • 明白了 - 是的,与 db 的想法相同,但不需要像 memcached 那样铁定?
    • 不要忘记在一段时间后使陈旧状态过期。大约 5 分钟就足够了。
    猜你喜欢
    • 1970-01-01
    • 2020-04-06
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 2019-05-09
    • 2017-08-14
    • 2021-09-05
    相关资源
    最近更新 更多