refactor: 使用 go-oidc 验证 ID Token
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user