【问题标题】:Golang sha256 hash not satisfying okta code challengeGolang sha256 哈希不满足 okta 代码挑战
【发布时间】:2020-05-12 19:14:12
【问题描述】:

我正在使用 golang 来实现针对 Okta 的 PKCE 身份验证流程。 Okta 需要至少 43 个字符的 url 安全字符串(验证者),然后计算 sha256 哈希,以 base64 URL 编码(质询)发送。 Okta PKCE Flow

我生成一个随机验证器。这是一个示例:aAOzSsxfONaAauKYKRABWUfZLFgVFZqgbJRaArwKAzhzEWurUAhDyzcTkSKLClFL

生成base64编码的sha256和:

        hasher := sha256.New()
        hasher.Write([]byte(login.CodeVerifier))
        codeChallenge := base64.URLEncoding.EncodeToString(hasher.Sum(nil))

当给定上面的示例verifier 时产生了一个挑战:1XvaG5_-p9OPfxH9yeLmSWu5zGHxW6Pjq_HrdSsI-kk=

然而,在完成对/token 端点的 POST 后,总是返回错误:

{
"error": "invalid_grant",
"error_description": "PKCE verification failed."
}

这是 POST 到 /token 的逻辑:

        code := r.URL.Query().Get("code")
        state := r.URL.Query().Get("state")
        log.Debug().Msgf("callback code:%s state:%s verifier:%s", code, state, loginCache[state])

        values := url.Values{}
        values.Set("grant_type", "authorization_code")
        values.Set("client_id", clientID)
        values.Set("redirect_uri", redirectURI)
        values.Set("code", code)
        values.Set("code_verifier", loginCache[state])

        request, _ := http.NewRequest("POST", oktaTokenURL, strings.NewReader(values.Encode()))
        request.URL.RawQuery = values.Encode()
        request.Header.Set("accept", "application/json")
        request.Header.Set("cache-control", "no-cache")
        request.Header.Set("content-type", "application/x-www-form-urlencoded")

        response, err := http.DefaultClient.Do(request)

【问题讨论】:

  • 程序将values编码为请求正文和请求查询字符串。两者都需要吗?这可能会导致问题吗?
  • 另外:创建请求后不要修改 URL(虽然这可能完全没问题,但它很丑陋。或者可能是错误的。)
  • request.URL.RawQuery = values.Encode() 不应该在那里。作为 POST,不应该有查询字符串值。但是,删除该行并不会更改错误消息。

标签: go okta pkce


【解决方案1】:

我不熟悉 Golang,但我认为问题在于您使用了错误的函数来进行 bas64 编码。 RFC 7636 状态

Base64url Encoding
      Base64 encoding using the URL- and filename-safe character set
      defined in Section 5 of [RFC4648], with all trailing '='
      characters omitted (as permitted by Section 3.2 of [RFC4648]) and
      without the inclusion of any line breaks, whitespace, or other
      additional characters.  (See Appendix A for notes on implementing
      base64url encoding without padding.)

查看base64 documentation in Govar RawStdEncoding = StdEncoding.WithPadding(NoPadding)应该输出正确的格式。

RawStdEncoding 是标准的原始、未填充的 base64 编码,如 RFC 4648 第 3.2 节中所定义。这与 StdEncoding 相同,但省略了填充字符。

【讨论】:

  • 这是个好主意,但我无法让它发挥作用。我看到了你引用的方法,但是错误信息没有变化。
  • 也许我来晚了,你可能已经修好了,但以防万一,我认为这里需要的是base64.RawURLEncoding
猜你喜欢
  • 2021-06-26
  • 2018-01-21
  • 1970-01-01
  • 2022-07-12
  • 2021-08-22
  • 2019-11-18
  • 2019-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多