elsa-workflows/elsa-core · error · OpenIdConnectAuthenticationException

The identity provider rejected the authentication request.

Error message

The identity provider rejected the authentication request.

What it means

During the OpenID Connect authorization-code callback, AuthenticateCallbackAsync first checks the query parameters returned by the identity provider. If the provider returned an 'error' parameter (per RFC 6749 section 4.1.2.1), the adapter throws this OpenIdConnectAuthenticationException, meaning the provider itself rejected the end user's authentication or authorization request.

Solutions

  1. Log the actual 'error' and 'error_description' query parameters from the callback URL to see why the provider rejected the request.
  2. Check the provider's app registration: client_id, redirect URI, and requested scopes must all be registered.
  3. Surface a friendly message to the end user explaining the login was cancelled or denied, and retry the sign-in flow via the adapter's initiation endpoint.

Example fix

// inspect the callback to diagnose
var error = Request.Query["error"].ToString();
var description = Request.Query["error_description"].ToString();
logger.LogWarning("OIDC callback rejected: {Error} - {Description}", error, description);
return Challenge(); // restart the login flow
Defensive patterns

Strategy: try-catch

Validate before calling

if (Request.Query.ContainsKey("error")) { var desc = Request.Query["error_description"].ToString(); return Results.Problem($"Login rejected: {Request.Query[\"error\"]} {desc}"); }

Try / catch

try { var result = await adapter.AuthenticateCallbackAsync(context); } catch (OpenIdConnectAuthenticationException ex) { logger.LogWarning(ex, "OIDC callback error"); return Challenge(); }

Prevention

When it happens

Trigger: Calling AuthenticateCallbackAsync with context.Parameters containing an 'error' key (e.g. error=access_denied, error=invalid_request) from the redirect URI callback.

Common situations: User cancels the login page; the provider rejects the request due to a misconfigured redirect URI, unregistered client, or missing user consent; the user's account is locked or lacks access to the application.

Understand the failure class

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/c4bf06fd04a6ac34. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.ExternalAuthentication.OpenIdConnect/Services/OpenIdConnectExternalAuthenticationAdapter.cs:82

        var query = new Dictionary<string, string>
        {
            ["response_type"] = "code",
            ["client_id"] = settings.ClientId,
            ["redirect_uri"] = GetCallbackUri(context.Connection, context.Transaction.Purpose).AbsoluteUri,
            ["scope"] = string.Join(' ', settings.Scopes),
            ["state"] = context.CorrelationState,
            ["nonce"] = nonce,
            ["code_challenge"] = CreateCodeChallenge(verifier),
            ["code_challenge_method"] = "S256"
        };

        return new(WithQuery(metadata.AuthorizationEndpoint, query), state);
    }

    public async ValueTask<ExternalAuthenticationResult> AuthenticateCallbackAsync(ExternalCallbackContext context, CancellationToken cancellationToken = default)
    {
        if (TryGetParameter(context.Parameters, "error", out _))
            throw new OpenIdConnectAuthenticationException("The identity provider rejected the authentication request.");

        if (!TryGetParameter(context.Parameters, "state", out var state) || !FixedTimeEquals(state, context.CorrelationState))
            throw new OpenIdConnectAuthenticationException("The identity provider callback could not be correlated.");

        var settings = await GetSettingsAsync(context.Connection.Connection.AdapterSettings, cancellationToken);
        var metadata = await ResolveMetadataAsync(settings, cancellationToken);
        var adapterState = ReadAdapterState(context.Transaction.ProtectedPayload);
        if (adapterState is not null && !string.Equals(adapterState.Issuer, metadata.Issuer, StringComparison.Ordinal))
            throw new OpenIdConnectAuthenticationException("The identity provider callback issuer did not match the initiated request.");

        var idToken = await ExchangeCodeAsync(settings, metadata, context, adapterState?.CodeVerifier, cancellationToken);
        var principal = await ValidateIdTokenAsync(idToken, settings, metadata, cancellationToken);
        var nonce = principal.FindFirst("nonce")?.Value;
        var expectedNonce = context.Transaction.ProviderNonce ?? adapterState?.Nonce;
        if (string.IsNullOrWhiteSpace(expectedNonce) || !FixedTimeEquals(nonce, expectedNonce))
            throw new OpenIdConnectAuthenticationException("The identity provider nonce did not match the initiated request.");

        var issuer = principal.FindFirst("iss")?.Value ?? metadata.Issuer;

View on GitHub (pinned to fe9217bdfa)