Replace github.com/stoggi/aws-oidc with git.narnian.us/lordwelch/aws-oidc Update import paths to git.narnian.us/lordwelch/sshrimp Remove unnecessary logging This reverts commit 2ae68a7e316f6f692a4773ba4d2702bf144d5155.
68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
package identity
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"regexp"
|
|
|
|
"git.narnian.us/lordwelch/sshrimp/internal/config"
|
|
"github.com/coreos/go-oidc"
|
|
)
|
|
|
|
// Identity holds information required to verify an OIDC identity token
|
|
type Identity struct {
|
|
ctx context.Context
|
|
verifier *oidc.IDTokenVerifier
|
|
usernameRE *regexp.Regexp
|
|
usernameClaim string
|
|
}
|
|
|
|
// NewIdentity return a new Identity, with default values and oidc proivder information populated
|
|
func NewIdentity(c *config.SSHrimp) (*Identity, error) {
|
|
ctx := context.Background()
|
|
provider, err := oidc.NewProvider(ctx, c.Agent.ProviderURL)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
oidcConfig := &oidc.Config{
|
|
ClientID: c.Agent.ClientID,
|
|
SupportedSigningAlgs: []string{"RS256"},
|
|
}
|
|
|
|
return &Identity{
|
|
ctx: ctx,
|
|
verifier: provider.Verifier(oidcConfig),
|
|
usernameRE: regexp.MustCompile(c.CertificateAuthority.UsernameRegex),
|
|
usernameClaim: c.CertificateAuthority.UsernameClaim,
|
|
}, nil
|
|
}
|
|
|
|
// Validate an identity token
|
|
func (i *Identity) Validate(token string) (string, error) {
|
|
|
|
idToken, err := i.verifier.Verify(i.ctx, token)
|
|
if err != nil {
|
|
return "", errors.New("failed to verify identity token: " + err.Error())
|
|
}
|
|
|
|
var claims map[string]interface{}
|
|
if err := idToken.Claims(&claims); err != nil {
|
|
return "", errors.New("failed to parse claims: " + err.Error())
|
|
}
|
|
|
|
claimedUsername, ok := claims[i.usernameClaim].(string)
|
|
if !ok {
|
|
return "", errors.New("configured username claim not in identity token")
|
|
}
|
|
|
|
return i.parseUsername(claimedUsername)
|
|
}
|
|
|
|
func (i *Identity) parseUsername(username string) (string, error) {
|
|
if match := i.usernameRE.FindStringSubmatch(username); match != nil {
|
|
return match[1], nil
|
|
}
|
|
return "", errors.New("unable to parse username from claim")
|
|
}
|