我正在使用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)
最佳答案
我对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 Go,
var RawStdEncoding = StdEncoding.WithPadding(NoPadding)
应该输出正确的格式。RawStdEncoding是标准的原始,未填充的base64编码,如RFC 4648第3.2节中所定义。这与StdEncoding相同,但是省略了填充字符。
关于go - Golang sha256哈希无法满足okta代码挑战,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61712066/