add the possibility to debug oauth or oidc login issues (#541)

This commit is contained in:
Christoph Haas
2025-10-12 15:09:40 +02:00
parent cdf3a49801
commit f53d0b3d7f
4 changed files with 76 additions and 30 deletions

View File

@@ -19,15 +19,16 @@ import (
// PlainOauthAuthenticator is an authenticator that uses OAuth for authentication.
// User information is retrieved from the specified user info endpoint.
type PlainOauthAuthenticator struct {
name string
cfg *oauth2.Config
userInfoEndpoint string
client *http.Client
userInfoMapping config.OauthFields
userAdminMapping *config.OauthAdminMapping
registrationEnabled bool
userInfoLogging bool
allowedDomains []string
name string
cfg *oauth2.Config
userInfoEndpoint string
client *http.Client
userInfoMapping config.OauthFields
userAdminMapping *config.OauthAdminMapping
registrationEnabled bool
userInfoLogging bool
sensitiveInfoLogging bool
allowedDomains []string
}
func newPlainOauthAuthenticator(
@@ -57,6 +58,7 @@ func newPlainOauthAuthenticator(
provider.userAdminMapping = &cfg.AdminMapping
provider.registrationEnabled = cfg.RegistrationEnabled
provider.userInfoLogging = cfg.LogUserInfo
provider.sensitiveInfoLogging = cfg.LogSensitiveInfo
provider.allowedDomains = cfg.AllowedDomains
return provider, nil
@@ -110,6 +112,10 @@ func (p PlainOauthAuthenticator) GetUserInfo(
response, err := p.client.Do(req)
if err != nil {
if p.sensitiveInfoLogging {
slog.Debug("OAuth: failed to get user info", "endpoint", p.userInfoEndpoint,
"token", token, "error", err)
}
return nil, fmt.Errorf("failed to get user info: %w", err)
}
defer internal.LogClose(response.Body)
@@ -121,11 +127,15 @@ func (p PlainOauthAuthenticator) GetUserInfo(
var userFields map[string]any
err = json.Unmarshal(contents, &userFields)
if err != nil {
if p.sensitiveInfoLogging {
slog.Debug("OAuth: failed to parse user info", "endpoint", p.userInfoEndpoint,
"token", token, "contents", contents, "error", err)
}
return nil, fmt.Errorf("failed to parse user info: %w", err)
}
if p.userInfoLogging {
slog.Debug("OAuth user info",
slog.Debug("OAuth: user info debug",
"source", p.name,
"info", string(contents))
}

View File

@@ -16,15 +16,16 @@ import (
// OidcAuthenticator is an authenticator for OpenID Connect providers.
type OidcAuthenticator struct {
name string
provider *oidc.Provider
verifier *oidc.IDTokenVerifier
cfg *oauth2.Config
userInfoMapping config.OauthFields
userAdminMapping *config.OauthAdminMapping
registrationEnabled bool
userInfoLogging bool
allowedDomains []string
name string
provider *oidc.Provider
verifier *oidc.IDTokenVerifier
cfg *oauth2.Config
userInfoMapping config.OauthFields
userAdminMapping *config.OauthAdminMapping
registrationEnabled bool
userInfoLogging bool
sensitiveInfoLogging bool
allowedDomains []string
}
func newOidcAuthenticator(
@@ -58,6 +59,7 @@ func newOidcAuthenticator(
provider.userAdminMapping = &cfg.AdminMapping
provider.registrationEnabled = cfg.RegistrationEnabled
provider.userInfoLogging = cfg.LogUserInfo
provider.sensitiveInfoLogging = cfg.LogSensitiveInfo
provider.allowedDomains = cfg.AllowedDomains
return provider, nil
@@ -102,24 +104,40 @@ func (o OidcAuthenticator) GetUserInfo(ctx context.Context, token *oauth2.Token,
) {
rawIDToken, ok := token.Extra("id_token").(string)
if !ok {
if o.sensitiveInfoLogging {
slog.Debug("OIDC: token does not contain id_token", "token", token, "nonce", nonce)
}
return nil, errors.New("token does not contain id_token")
}
idToken, err := o.verifier.Verify(ctx, rawIDToken)
if err != nil {
if o.sensitiveInfoLogging {
slog.Debug("OIDC: failed to validate id_token", "token", token, "id_token", rawIDToken, "nonce", nonce,
"error",
err)
}
return nil, fmt.Errorf("failed to validate id_token: %w", err)
}
if idToken.Nonce != nonce {
if o.sensitiveInfoLogging {
slog.Debug("OIDC: id_token nonce mismatch", "token", token, "id_token", idToken, "nonce", nonce)
}
return nil, errors.New("nonce mismatch")
}
var tokenFields map[string]any
if err = idToken.Claims(&tokenFields); err != nil {
if o.sensitiveInfoLogging {
slog.Debug("OIDC: failed to parse extra claims", "token", token, "id_token", idToken, "nonce", nonce,
"error",
err)
}
return nil, fmt.Errorf("failed to parse extra claims: %w", err)
}
if o.userInfoLogging {
contents, _ := json.Marshal(tokenFields)
slog.Debug("OIDC user info",
slog.Debug("OIDC: user info debug",
"source", o.name,
"info", string(contents))
}