refactor: 使用 go-oidc 验证 ID Token

This commit is contained in:
2026-07-14 11:11:48 +08:00
parent 053bc260c7
commit 85d72a1c8c
7 changed files with 91 additions and 69 deletions
@@ -2,6 +2,9 @@ package auth
import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/json"
@@ -11,6 +14,8 @@ import (
"net/url"
"strings"
"testing"
"github.com/golang-jwt/jwt/v5"
)
func TestOIDCPublicClientUsesAuthorizationCodePKCES256WithoutSecret(t *testing.T) {
@@ -85,6 +90,50 @@ func TestOIDCPublicClientRejectsOfflineAccess(t *testing.T) {
}
}
func TestOIDCPublicClientVerifiesIDTokenNonceAndAudience(t *testing.T) {
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
var issuer string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
switch r.URL.Path {
case "/.well-known/openid-configuration":
_ = json.NewEncoder(w).Encode(map[string]any{
"issuer": issuer, "authorization_endpoint": issuer + "/authorize",
"token_endpoint": issuer + "/token", "jwks_uri": issuer + "/jwks",
"id_token_signing_alg_values_supported": []string{"RS256", "ES256"},
})
case "/jwks":
_ = json.NewEncoder(w).Encode(map[string]any{"keys": []any{ecJWK("ec-key", &key.PublicKey)}})
default:
http.NotFound(w, r)
}
}))
defer server.Close()
issuer = server.URL
client, err := NewOIDCPublicClient(OIDCPublicClientConfig{
Issuer: issuer, ClientID: "gateway-public-client", RedirectURI: "https://gateway.example.com/callback",
PostLogoutRedirectURI: "https://gateway.example.com/", HTTPClient: server.Client(),
})
if err != nil {
t.Fatal(err)
}
idToken := signedOIDCToken(t, issuer, "ec-key", jwt.SigningMethodES256, key, func(claims jwt.MapClaims) {
claims["aud"] = "gateway-public-client"
claims["nonce"] = "expected-nonce"
})
subject, err := client.VerifyIDToken(context.Background(), idToken, "expected-nonce")
if err != nil || subject != "platform-subject" {
t.Fatalf("VerifyIDToken() subject=%q err=%v", subject, err)
}
if _, err := client.VerifyIDToken(context.Background(), idToken, "wrong-nonce"); err == nil {
t.Fatal("ID token with mismatched nonce was accepted")
}
}
func TestOIDCPublicClientRefreshAndRevokeNeverSendSecret(t *testing.T) {
var issuer string
requests := 0