Or, it’s not IdentityServer, it’s you.
A common issue with when integrating with an OpenID Provider, such as IdentityServer4, is getting caught in an infinite redirect loop. Typically, this redirect loop will eventually crash your browser tab, or the browser itself.
In Chrome, you’d get the ERR_TOO_MANY_REDIRECTS
error message.
Or, if you’re issuing cookies to track nonce and states values with each redirect and not cleaning up after yourself (I’m looking at you OWIN/Katana), then you’ll probably get an a 400 Bad Request, with a message of something like “The size of the request headers is too long”.
If you’re using Firefox or Edge, then you’ll see something similar, albeit a bit more cryptic.
What is Causing the Loop?
This redirect loop is a common symptom to a few different errors, and before we look at some common issues and debug steps, let’s take a look at what this redirect loop actually is, and what is causing it.
The high-level process is:
- The client application issues an authentication challenge (either manually or as the result of a 401)
- The client redirects the browser (302) to IdentityServer, issuing an authorization request
- The request is validated by IdentityServer and IdentityServer authenticates the user (they may be challenged for credentials, or IdentityServer may already have a session for that user)
- IdentityServer generates codes/tokens and sends them back to the client application
- The client application validates the identity token and decides whether or not to start its own session
- Something goes wrong
- The user does not have a session
- Go back to step 1 and repeat to insanity
So, if IdentityServer validated the request successfully (i.e., you didn’t get an error response such as unauthorized_client
or invalid_request
), then the fault is not with IdentityServer, it’s within the client application.
For whatever reason, it is struggling to use the tokens returned by IdentityServer and is getting upset with us.
Debug Steps
Check your Identity Token
The first thing to check is the identity token. Is the payload what you expect? For example, is the intended audience your client id? Is the issuer what you expected? Is the signature valid? Are the datetime values what you expect and valid in the eyes of the client app (check for clock skew)?
Basically, work through the validation steps that your client application is performing against the identity token and see if that’s the reason it is failing.
Is a Cookie Being Set?
Is your client application starting a session?
For example, look for the Set-Cookie
response header being issued by your client application.
If it’s there, check the next request to see if that same cookie is in the Cookie
header.
In the past, I’ve seen applications signal that a session has been created, but then the response didn’t include the Set-Cookie
header.
So, a cookie was being created but not sent back to the browser.
What’s the use in that?!
If you’re using ASP.NET 4.x and OWIN/Katana, this was a common issue known as the System.Web Cookie Monster.
Another variation on this is if the Set-Cookie
header is sent, but then on the next request, the browser does not set the Cookie
header.
This could be that the browser did not save the cookie, or if it cannot access the cookie on the next request.
My recommendation here is to see if the behavior persists when using the browsers incognito/private mode with no browser extensions enabled.
Another culprit can be something in your network stack.
If the cookie is being set and then used but is still not trusted, it might be that the cookie is being truncated. Or maybe you don’t have the correct tools to read the cookie (e.g., the wrong key to unencrypt it).
401 vs. 403
Is your client application returning a 401 Unauthorized instead of a 403 Forbidden? If the user is authenticated but is not allowed to perform the action they are requesting, then you should be returning a 403 forbidden.
If you are returning a 401 for this kind of action, it may be causing a handler in your application to redirect off to the identity provider.
Scheme Consistency
All of your OpenID Connect and OAuth participants should be using TLS (https), but in development, this might not be the case. If so, try and keep all of your dev instances on the same scheme. This includes redirect URIs (a very common issue in the IdentityServer4 community).
What About You?
Have you had bizarre redirect loop issues that you’d like to share? Do you want to scream your frustration into the void of an unmonitored comments section? Then feel free to let me know in the section below!