forked from TrueCloudLab/certificates
Add iss#sub uri in OIDC certificates.
Admin will use the CR template if none is provided.
This commit is contained in:
parent
9bd576af2c
commit
71be83b25e
2 changed files with 40 additions and 21 deletions
|
@ -74,10 +74,12 @@ type OIDC struct {
|
||||||
// IsAdmin returns true if the given email is in the Admins allowlist, false
|
// IsAdmin returns true if the given email is in the Admins allowlist, false
|
||||||
// otherwise.
|
// otherwise.
|
||||||
func (o *OIDC) IsAdmin(email string) bool {
|
func (o *OIDC) IsAdmin(email string) bool {
|
||||||
email = sanitizeEmail(email)
|
if email != "" {
|
||||||
for _, e := range o.Admins {
|
email = sanitizeEmail(email)
|
||||||
if email == sanitizeEmail(e) {
|
for _, e := range o.Admins {
|
||||||
return true
|
if email == sanitizeEmail(e) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -205,13 +207,8 @@ func (o *OIDC) ValidatePayload(p openIDPayload) error {
|
||||||
return errs.Unauthorized("validatePayload: failed to validate oidc token payload: invalid azp")
|
return errs.Unauthorized("validatePayload: failed to validate oidc token payload: invalid azp")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce an email claim
|
|
||||||
if p.Email == "" {
|
|
||||||
return errs.Unauthorized("validatePayload: failed to validate oidc token payload: email not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate domains (case-insensitive)
|
// Validate domains (case-insensitive)
|
||||||
if !o.IsAdmin(p.Email) && len(o.Domains) > 0 {
|
if p.Email != "" && len(o.Domains) > 0 && !o.IsAdmin(p.Email) {
|
||||||
email := sanitizeEmail(p.Email)
|
email := sanitizeEmail(p.Email)
|
||||||
var found bool
|
var found bool
|
||||||
for _, d := range o.Domains {
|
for _, d := range o.Domains {
|
||||||
|
@ -304,15 +301,38 @@ func (o *OIDC) AuthorizeSign(ctx context.Context, token string) ([]SignOption, e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Certificate templates
|
// Certificate templates
|
||||||
data := x509util.CreateTemplateData(claims.Subject, []string{claims.Email})
|
sans := []string{}
|
||||||
|
if claims.Email != "" {
|
||||||
|
sans = append(sans, claims.Email)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add uri SAN with iss#sub if issuer is a URL with schema.
|
||||||
|
//
|
||||||
|
// According to https://openid.net/specs/openid-connect-core-1_0.html the
|
||||||
|
// iss value is a case sensitive URL using the https scheme that contains
|
||||||
|
// scheme, host, and optionally, port number and path components and no
|
||||||
|
// query or fragment components.
|
||||||
|
if iss, err := url.Parse(claims.Issuer); err == nil && iss.Scheme != "" {
|
||||||
|
iss.Fragment = claims.Subject
|
||||||
|
sans = append(sans, iss.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
data := x509util.CreateTemplateData(claims.Subject, sans)
|
||||||
data.SetToken(claims)
|
data.SetToken(claims)
|
||||||
|
|
||||||
templateOptions, err := TemplateOptions(o.Options, data)
|
// Use the default template unless no-templates are configured and email is
|
||||||
|
// an admin, in that case we will use the CR template.
|
||||||
|
defaultTemplate := x509util.DefaultLeafTemplate
|
||||||
|
if !o.Options.HasTemplate() && o.IsAdmin(claims.Email) {
|
||||||
|
defaultTemplate = x509util.CertificateRequestTemplate
|
||||||
|
}
|
||||||
|
|
||||||
|
templateOptions, err := CustomTemplateOptions(o.Options, data, defaultTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSign")
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSign")
|
||||||
}
|
}
|
||||||
|
|
||||||
so := []SignOption{
|
return []SignOption{
|
||||||
templateOptions,
|
templateOptions,
|
||||||
// modifiers / withOptions
|
// modifiers / withOptions
|
||||||
newProvisionerExtensionOption(TypeOIDC, o.Name, o.ClientID),
|
newProvisionerExtensionOption(TypeOIDC, o.Name, o.ClientID),
|
||||||
|
@ -320,13 +340,7 @@ func (o *OIDC) AuthorizeSign(ctx context.Context, token string) ([]SignOption, e
|
||||||
// validators
|
// validators
|
||||||
defaultPublicKeyValidator{},
|
defaultPublicKeyValidator{},
|
||||||
newValidityValidator(o.claimer.MinTLSCertDuration(), o.claimer.MaxTLSCertDuration()),
|
newValidityValidator(o.claimer.MinTLSCertDuration(), o.claimer.MaxTLSCertDuration()),
|
||||||
}
|
}, nil
|
||||||
// Admins should be able to authorize any SAN
|
|
||||||
if o.IsAdmin(claims.Email) {
|
|
||||||
return so, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return append(so, emailOnlyIdentity(claims.Email)), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthorizeRenew returns an error if the renewal is disabled.
|
// AuthorizeRenew returns an error if the renewal is disabled.
|
||||||
|
|
|
@ -35,6 +35,11 @@ type ProvisionerOptions struct {
|
||||||
TemplateData json.RawMessage `json:"templateData"`
|
TemplateData json.RawMessage `json:"templateData"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasTemplate returns true if a template is defined in the provisioner options.
|
||||||
|
func (o *ProvisionerOptions) HasTemplate() bool {
|
||||||
|
return o != nil && (o.Template != "" || o.TemplateFile != "")
|
||||||
|
}
|
||||||
|
|
||||||
// TemplateOptions generates a CertificateOptions with the template and data
|
// TemplateOptions generates a CertificateOptions with the template and data
|
||||||
// defined in the ProvisionerOptions, the provisioner generated data, and the
|
// defined in the ProvisionerOptions, the provisioner generated data, and the
|
||||||
// user data provided in the request. If no template has been provided,
|
// user data provided in the request. If no template has been provided,
|
||||||
|
@ -63,7 +68,7 @@ func CustomTemplateOptions(o *ProvisionerOptions, data x509util.TemplateData, de
|
||||||
|
|
||||||
return certificateOptionsFunc(func(so Options) []x509util.Option {
|
return certificateOptionsFunc(func(so Options) []x509util.Option {
|
||||||
// We're not provided user data without custom templates.
|
// We're not provided user data without custom templates.
|
||||||
if o == nil || (o.Template == "" && o.TemplateFile == "") {
|
if !o.HasTemplate() {
|
||||||
return []x509util.Option{
|
return []x509util.Option{
|
||||||
x509util.WithTemplate(defaultTemplate, data),
|
x509util.WithTemplate(defaultTemplate, data),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue