Repository navigation
Description
When an OIDC client has RequireConsent = true, the Security Service enters an infinite redirect loop:
/connect/authorize
→ /Consent?returnUrl=...
→ /connect/authorize
→ /Consent
The browser eventually displays:
ERR_TOO_MANY_REDIRECTS
Root cause
OidcRequestHandler redirects explicit-consent requests to /Consent.
However, /Consent is a new HTTP request. The OpenIddict request is not automatically available, so:
HttpContext.GetOpenIddictServerRequest()returns null.
ConsentRequestHandler treats the missing request as a direct or invalid visit and redirects back to the original returnUrl. This sends the browser back to /connect/authorize, which redirects to /Consent again.
Affected code
SecurityService.BusinessLogic/Oidc/OidcRequestHandler.csSecurityService.BusinessLogic/RequestHandlers/ConsentRequestHandler.csSecurityService/Pages/Consent/Index.cshtml.cs
The redirect to the consent page occurs in OidcRequestHandler.cs.
The redirect back to the original URL occurs when the OpenIddict request is unavailable in ConsentRequestHandler.cs.
Steps to reproduce
-
Register an OIDC client with:
RequireConsent = true ConsentType = explicit -
Start the Security Service.
-
Start an OIDC client application.
-
Begin the login flow.
-
Authenticate successfully.
-
Allow the client to require consent.
Expected behavior
The consent page should display:
- Client name
- Requested identity scopes
- Requested API scopes
- Accept and deny buttons
After accepting or denying consent, the user should be redirected back to the client callback URL.
Actual behavior
The browser continuously redirects between:
/connect/authorize
and:
/Consent?returnUrl=...
Eventually the browser reports:
ERR_TOO_MANY_REDIRECTS
Workaround
Set the client to use implicit consent:
RequireConsent = false
ConsentType = implicit
This bypasses the consent page but does not fix the underlying consent implementation.
Suggested fix
Preserve or reload the OpenIddict authorization transaction when /Consent is requested.
The consent page should be able to:
- Recover the original authorization request.
- Load the client and requested scopes.
- Render the consent page.
- Process accept or deny actions.
- Redirect back to the original authorization URL with the appropriate consent result.
The implementation should not depend on GetOpenIddictServerRequest() being populated on the separate /Consent request unless the authorization transaction is explicitly restored first.
Required tests
Add integration tests covering:
- Explicit consent page renders successfully.
- Accepting consent redirects to the client callback.
- Denying consent redirects with an access-denied response.
- Missing or invalid consent transactions return a controlled error rather than redirecting indefinitely.
- Implicit-consent clients continue to authorize without displaying the consent page.
Activity