mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-17 04:37:48 +00:00
fixup! fixup! fixup! fixup! Weekend fun with further optimisations.
This commit is contained in:
@@ -662,100 +662,6 @@ func (t *TraefikOidc) startMetadataRefresh(providerURL string) {
|
||||
}()
|
||||
}
|
||||
|
||||
// discoverProviderMetadata fetches OIDC provider metadata from the .well-known endpoint.
|
||||
// It constructs the well-known URL, uses retry logic for resilient fetching,
|
||||
// and returns the parsed provider metadata.
|
||||
// Parameters:
|
||||
// - providerURL: The base URL of the OIDC provider.
|
||||
// - httpClient: The HTTP client to use for the request.
|
||||
// - l: Logger instance for error and debug logging.
|
||||
//
|
||||
// Returns:
|
||||
// - The parsed ProviderMetadata containing endpoint URLs.
|
||||
// - An error if fetching fails after all retries or if a timeout is exceeded.
|
||||
func discoverProviderMetadata(providerURL string, httpClient *http.Client, l *Logger) (*ProviderMetadata, error) {
|
||||
wellKnownURL := strings.TrimSuffix(providerURL, "/") + "/.well-known/openid-configuration"
|
||||
|
||||
retryConfig := RetryConfig{
|
||||
MaxAttempts: 2,
|
||||
InitialDelay: 10 * time.Millisecond,
|
||||
MaxDelay: 50 * time.Millisecond,
|
||||
BackoffFactor: 2.0,
|
||||
EnableJitter: true,
|
||||
RetryableErrors: []string{
|
||||
"connection refused",
|
||||
"timeout",
|
||||
"temporary failure",
|
||||
"network unreachable",
|
||||
"no route to host",
|
||||
"connection reset",
|
||||
"status code 500",
|
||||
"status code 502",
|
||||
"status code 503",
|
||||
"status code 504",
|
||||
},
|
||||
}
|
||||
|
||||
retryExecutor := NewRetryExecutor(retryConfig, l)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var metadata *ProviderMetadata
|
||||
err := retryExecutor.ExecuteWithContext(ctx, func() error {
|
||||
var fetchErr error
|
||||
metadata, fetchErr = fetchMetadata(wellKnownURL, httpClient)
|
||||
return fetchErr
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
l.Errorf("Failed to fetch provider metadata after retries: %v", err)
|
||||
return nil, fmt.Errorf("failed to fetch provider metadata: %w", err)
|
||||
}
|
||||
|
||||
l.Debug("Provider metadata fetched successfully")
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
// fetchMetadata performs the actual HTTP request to fetch provider metadata.
|
||||
// It makes a GET request to the .well-known URL, validates the response,
|
||||
// and decodes the JSON metadata.
|
||||
// Parameters:
|
||||
// - wellKnownURL: The complete URL to the .well-known/openid-configuration endpoint.
|
||||
// - httpClient: The HTTP client to use for the request.
|
||||
//
|
||||
// Returns:
|
||||
// - The parsed ProviderMetadata from the response.
|
||||
// - An error if the GET request fails, the status code is not 200 OK, or JSON decoding fails.
|
||||
func fetchMetadata(wellKnownURL string, httpClient *http.Client) (*ProviderMetadata, error) {
|
||||
resp, err := httpClient.Get(wellKnownURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch provider metadata: %w", err)
|
||||
}
|
||||
if resp == nil {
|
||||
return nil, fmt.Errorf("received nil response from provider at %s", wellKnownURL)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if resp != nil && resp.Body != nil {
|
||||
io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
limitReader := io.LimitReader(resp.Body, 1024*10)
|
||||
bodyBytes, _ := io.ReadAll(limitReader)
|
||||
return nil, fmt.Errorf("failed to fetch provider metadata from %s: status code %d, body: %s", wellKnownURL, resp.StatusCode, string(bodyBytes))
|
||||
}
|
||||
|
||||
var metadata ProviderMetadata
|
||||
if err := json.NewDecoder(resp.Body).Decode(&metadata); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode provider metadata from %s: %w", wellKnownURL, err)
|
||||
}
|
||||
|
||||
return &metadata, nil
|
||||
}
|
||||
|
||||
// ServeHTTP implements the main middleware logic for processing HTTP requests.
|
||||
// It handles the complete OIDC authentication flow including:
|
||||
// - Excluded URL bypass
|
||||
|
||||
Reference in New Issue
Block a user