allow missing Email claim in OIDC tokens, use subject when its missing

This commit is contained in:
Raal Goff 2022-09-05 12:43:32 +08:00
parent d718c69ad3
commit 7a03c43fe2

View file

@ -376,31 +376,46 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption
if err != nil { if err != nil {
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSSHSign") return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSSHSign")
} }
// Enforce an email claim
if claims.Subject == "" {
return nil, errs.Unauthorized("oidc.AuthorizeSSHSign: failed to validate oidc token payload: subject not found")
}
var data sshutil.TemplateData
var principals []string
if claims.Email == "" { if claims.Email == "" {
return nil, errs.Unauthorized("oidc.AuthorizeSSHSign: failed to validate oidc token payload: email not found") // If email is empty, use the Subject claim instead to create minimal data for the template to use
} data = sshutil.CreateTemplateData(sshutil.UserCert, claims.Subject, nil)
if v, err := unsafeParseSigned(token); err == nil {
data.SetToken(v)
}
// Get the identity using either the default identityFunc or one injected principals = nil
// externally. Note that the PreferredUsername might be empty. } else {
// TBD: Would preferred_username present a safety issue here? // Get the identity using either the default identityFunc or one injected
iden, err := o.ctl.GetIdentity(ctx, claims.Email) // externally. Note that the PreferredUsername might be empty.
if err != nil { // TBD: Would preferred_username present a safety issue here?
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSSHSign") iden, err := o.ctl.GetIdentity(ctx, claims.Email)
} if err != nil {
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSSHSign")
}
// Certificate templates. // Certificate templates.
data := sshutil.CreateTemplateData(sshutil.UserCert, claims.Email, iden.Usernames) data = sshutil.CreateTemplateData(sshutil.UserCert, claims.Email, iden.Usernames)
if v, err := unsafeParseSigned(token); err == nil { if v, err := unsafeParseSigned(token); err == nil {
data.SetToken(v) data.SetToken(v)
} }
// Add custom extensions added in the identity function. // Add custom extensions added in the identity function.
for k, v := range iden.Permissions.Extensions { for k, v := range iden.Permissions.Extensions {
data.AddExtension(k, v) data.AddExtension(k, v)
} }
// Add custom critical options added in the identity function. // Add custom critical options added in the identity function.
for k, v := range iden.Permissions.CriticalOptions { for k, v := range iden.Permissions.CriticalOptions {
data.AddCriticalOption(k, v) data.AddCriticalOption(k, v)
}
principals = iden.Usernames
} }
// Use the default template unless no-templates are configured and email is // Use the default template unless no-templates are configured and email is
@ -429,7 +444,7 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption
} else { } else {
signOptions = append(signOptions, sshCertOptionsValidator(SignSSHOptions{ signOptions = append(signOptions, sshCertOptionsValidator(SignSSHOptions{
CertType: SSHUserCert, CertType: SSHUserCert,
Principals: iden.Usernames, Principals: principals,
})) }))
} }