feat: allow OIDC providers which do not have email_verified claim

This fix allows using OIDC login for Azure or other similar Auth Systems.
Fixes: https://github.com/siderolabs/omni/issues/1818

Signed-off-by: lkc8fe <lukas.reckzuegel@de.bosch.com>
This commit is contained in:
lkc8fe 2025-11-10 11:46:59 +01:00 committed by Artem Chernyshev
parent 119c20da3f
commit 1dec8ed740
No known key found for this signature in database
GPG Key ID: 9BAC0E08F5067BB8
4 changed files with 21 additions and 11 deletions

View File

@ -475,6 +475,9 @@ func defineAuthFlags() {
rootCmd.Flags().StringVar(&cmdConfig.Auth.OIDC.LogoutURL, "auth-oidc-logout-url", cmdConfig.Auth.OIDC.LogoutURL,
"OIDC logout URL.")
rootCmd.Flags().BoolVar(&cmdConfig.Auth.OIDC.AllowUnverifiedEmail, "auth-oidc-allow-unverified-email", cmdConfig.Auth.OIDC.AllowUnverifiedEmail,
"Allow OIDC tokens without email_verified claim.")
}
func defineLogsFlags() {

View File

@ -511,6 +511,7 @@ func (s *Server) getAuthInterceptors(ctx context.Context) ([]interceptorCreator,
ctx,
s.oidcProvider,
config.Config.Auth.OIDC.ClientID,
config.Config.Auth.OIDC.AllowUnverifiedEmail,
)
if err != nil {
return nil, err

View File

@ -9,6 +9,7 @@ import (
"context"
"fmt"
"net/mail"
"strings"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/siderolabs/go-api-signature/pkg/jwt"
@ -16,17 +17,21 @@ import (
// IDTokenVerifier is an Auth0 ID token verifier.
type IDTokenVerifier struct {
verifier *oidc.IDTokenVerifier
verifier *oidc.IDTokenVerifier
allowUnverifiedEmail bool
}
// NewIDTokenVerifier creates a new ID token verifier.
func NewIDTokenVerifier(ctx context.Context, provider *oidc.Provider, clientID string) (*IDTokenVerifier, error) {
func NewIDTokenVerifier(ctx context.Context, provider *oidc.Provider, clientID string,
allowUnverifiedEmail bool,
) (*IDTokenVerifier, error) {
verifier := provider.Verifier(&oidc.Config{
ClientID: clientID,
})
return &IDTokenVerifier{
verifier: verifier,
verifier: verifier,
allowUnverifiedEmail: allowUnverifiedEmail,
}, nil
}
@ -51,12 +56,12 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, token string) (*jwt.Claims
return nil, fmt.Errorf("email claim is not valid: %w: %s", err, claims.Email)
}
if !claims.EmailVerified {
if !claims.EmailVerified && !v.allowUnverifiedEmail {
return nil, &EmailNotVerifiedError{Email: claims.Email}
}
return &jwt.Claims{
VerifiedEmail: claims.Email,
VerifiedEmail: strings.ToLower(claims.Email),
}, nil
}

View File

@ -62,12 +62,13 @@ type WebAuthn struct {
// OIDC holds the configuration parameters for OIDC auth.
type OIDC struct {
ProviderURL string `yaml:"providerURL"`
ClientID string `yaml:"clientID"`
ClientSecret string `yaml:"clientSecret"`
LogoutURL string `yaml:"logoutURL"`
Scopes []string `yaml:"scopes"`
Enabled bool `yaml:"enabled"`
ProviderURL string `yaml:"providerURL"`
ClientID string `yaml:"clientID"`
ClientSecret string `yaml:"clientSecret"`
LogoutURL string `yaml:"logoutURL"`
Scopes []string `yaml:"scopes"`
Enabled bool `yaml:"enabled"`
AllowUnverifiedEmail bool `yaml:"allowUnverifiedEmail"`
}
// SAML holds configuration parameters for SAML auth.