54 lines
1.3 KiB
Go
54 lines
1.3 KiB
Go
package identity
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/coreos/go-oidc/v3/oidc"
|
|
)
|
|
|
|
var ErrInvalidToken = errors.New("invalid access token")
|
|
|
|
type TokenVerifier interface {
|
|
Verify(context.Context, string) (Principal, error)
|
|
}
|
|
|
|
type OIDCVerifier struct {
|
|
verifier *oidc.IDTokenVerifier
|
|
}
|
|
|
|
func NewOIDCVerifier(ctx context.Context, issuerURL, jwksURL, audience string) *OIDCVerifier {
|
|
keySet := oidc.NewRemoteKeySet(ctx, jwksURL)
|
|
return &OIDCVerifier{
|
|
verifier: oidc.NewVerifier(issuerURL, keySet, &oidc.Config{ClientID: audience}),
|
|
}
|
|
}
|
|
|
|
func (v *OIDCVerifier) Verify(ctx context.Context, rawToken string) (Principal, error) {
|
|
rawToken = strings.TrimSpace(rawToken)
|
|
if rawToken == "" {
|
|
return Principal{}, ErrInvalidToken
|
|
}
|
|
token, err := v.verifier.Verify(ctx, rawToken)
|
|
if err != nil {
|
|
return Principal{}, ErrInvalidToken
|
|
}
|
|
var claims struct {
|
|
Name string `json:"name"`
|
|
PreferredUsername string `json:"preferred_username"`
|
|
}
|
|
if err := token.Claims(&claims); err != nil {
|
|
return Principal{}, ErrInvalidToken
|
|
}
|
|
if token.Issuer == "" || token.Subject == "" {
|
|
return Principal{}, ErrInvalidToken
|
|
}
|
|
return Principal{
|
|
Issuer: token.Issuer,
|
|
Subject: token.Subject,
|
|
DisplayName: claims.Name,
|
|
PreferredUsername: claims.PreferredUsername,
|
|
}, nil
|
|
}
|