refactor: 统一 PKCE 挑战值生成逻辑
This commit is contained in:
parent
85d72a1c8c
commit
dd1ddd6ead
@ -48,7 +48,7 @@ func (s *Server) startOIDCLogin(w http.ResponseWriter, r *http.Request) {
|
||||
if returnTo == "" {
|
||||
returnTo = "/"
|
||||
}
|
||||
transaction, _, err := oidcsession.NewLoginTransaction(returnTo, time.Now())
|
||||
transaction, err := oidcsession.NewLoginTransaction(returnTo, time.Now())
|
||||
if err != nil {
|
||||
writeError(w, http.StatusBadRequest, "登录后返回地址无效", errorCodeOIDCLoginInvalid)
|
||||
return
|
||||
|
||||
@ -66,7 +66,7 @@ func TestCompleteOIDCLoginReportsSafeTransactionFailureReason(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
transaction, _, err := oidcsession.NewLoginTransaction("/", time.Now())
|
||||
transaction, err := oidcsession.NewLoginTransaction("/", time.Now())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package oidcsession
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"net/url"
|
||||
@ -22,25 +21,23 @@ type LoginTransaction struct {
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
func NewLoginTransaction(returnTo string, now time.Time) (LoginTransaction, string, error) {
|
||||
func NewLoginTransaction(returnTo string, now time.Time) (LoginTransaction, error) {
|
||||
if !ValidReturnTo(returnTo) {
|
||||
return LoginTransaction{}, "", errors.New("returnTo must be a same-origin relative path")
|
||||
return LoginTransaction{}, errors.New("returnTo must be a same-origin relative path")
|
||||
}
|
||||
state, err := randomBase64URL(32)
|
||||
if err != nil {
|
||||
return LoginTransaction{}, "", err
|
||||
return LoginTransaction{}, err
|
||||
}
|
||||
nonce, err := randomBase64URL(32)
|
||||
if err != nil {
|
||||
return LoginTransaction{}, "", err
|
||||
return LoginTransaction{}, err
|
||||
}
|
||||
verifier, err := randomBase64URL(32)
|
||||
if err != nil {
|
||||
return LoginTransaction{}, "", err
|
||||
return LoginTransaction{}, err
|
||||
}
|
||||
challengeHash := sha256.Sum256([]byte(verifier))
|
||||
return LoginTransaction{State: state, Nonce: nonce, PKCEVerifier: verifier, ReturnTo: returnTo, CreatedAt: now.UTC()},
|
||||
base64.RawURLEncoding.EncodeToString(challengeHash[:]), nil
|
||||
return LoginTransaction{State: state, Nonce: nonce, PKCEVerifier: verifier, ReturnTo: returnTo, CreatedAt: now.UTC()}, nil
|
||||
}
|
||||
|
||||
func (c *Cipher) EncodeLoginTransaction(transaction LoginTransaction) (string, error) {
|
||||
|
||||
@ -7,15 +7,15 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestLoginTransactionIsEncryptedBoundedAndPKCES256(t *testing.T) {
|
||||
func TestLoginTransactionIsEncryptedAndBounded(t *testing.T) {
|
||||
now := time.Date(2026, 7, 13, 12, 0, 0, 0, time.UTC)
|
||||
cipher, _ := NewCipher(bytes.Repeat([]byte{9}, 32))
|
||||
transaction, challenge, err := NewLoginTransaction("/workspace?tab=wallet", now)
|
||||
transaction, err := NewLoginTransaction("/workspace?tab=wallet", now)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if transaction.State == transaction.Nonce || len(challenge) != 43 || challenge == transaction.PKCEVerifier {
|
||||
t.Fatal("state, nonce and PKCE values are not independent S256 material")
|
||||
if transaction.State == transaction.Nonce || len(transaction.PKCEVerifier) != 43 || transaction.State == transaction.PKCEVerifier {
|
||||
t.Fatal("state, nonce and PKCE verifier are not independent security material")
|
||||
}
|
||||
encoded, err := cipher.EncodeLoginTransaction(transaction)
|
||||
if err != nil {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user