Too many redirect error is coming for some users -OPENID connect with MVC application

Hi Team,

I m using an MVC application with .net framework 4.7.2. I am using openID connect with OKTA.
This is working perfectly in lower environment(QA and UAT). But once the code moved to Production the below issues are coming.

  1. At the same time multiple users can able to login with OKTA and after few minutes if the same set of users are tring to login, it is throwing error as TOO many redirect.

  2. At the sametime if some other user trying to login it is working finr for them.

  3. It is inconsitent behvior.

Code used in startup page

public void Configuration(IAppBuilder app)
{

        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            ClientId = clientId,
            ClientSecret = clientSecret,
            Authority = authority,
            RedirectUri = redirectUri,
            ResponseType = OpenIdConnectResponseType.CodeIdToken,
            Scope = OpenIdConnectScope.OpenIdProfile,
            PostLogoutRedirectUri = postLogoutRedirectUri,
            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name"
            },
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthenticationFailed = n =>
                {
                    n.Exception.Message.ToString();
                    SemanticLogger.Log.Information("Exception from OKTA : " + n.Exception.Message.ToString());
                    SemanticLogger.Log.OKTAFileLogInformation("Exception from OKTA : " + n.Exception.Message.ToString());
                    return Task.CompletedTask;
                },

                MessageReceived = n =>
                {
                    //n.OwinContext.Response.Body.ToString();
                    SemanticLogger.Log.Information("Response received from OKTA : " + ((Microsoft.Owin.OwinResponse)n.OwinContext.Response).ReasonPhrase);
                    SemanticLogger.Log.Information("Response code received from OKTA : " + n.OwinContext.Response.StatusCode);
                    SemanticLogger.Log.OKTAFileLogInformation("Response received from OKTA : " + ((Microsoft.Owin.OwinResponse)n.OwinContext.Response).ReasonPhrase);
                    SemanticLogger.Log.OKTAFileLogInformation("Response code received from OKTA : " + n.OwinContext.Response.StatusCode);
                    return Task.CompletedTask;
                },

                AuthorizationCodeReceived = async n =>
                {
                    // Exchange code for access and ID tokens
                    var tokenClient = new TokenClient(authority + "/v1/token", clientId, clientSecret);
                    var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, redirectUri); 
                    if (tokenResponse != null && tokenResponse.IsError)
                    {
                        SemanticLogger.Log.OKTAFilLogError("Error received in tokenResponse from OKTA : " + tokenResponse.Error.ToString() + Environment.NewLine);
                        SemanticLogger.Log.Error("Error received in tokenResponse from OKTA : " + tokenResponse.Error.ToString());
                        throw new Exception(tokenResponse.Error);
                    } 
                    if (tokenResponse != null)
                    {
                        SemanticLogger.Log.OKTAFileLogInformation("TokenResponse received from OKTA : " + System.Text.Json.JsonSerializer.Serialize(tokenResponse) + Environment.NewLine);
                        var userInfoClient = new UserInfoClient(authority + "/v1/userinfo");
                        var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken); 
                        var claims = new List<Claim>();
                        if (userInfoResponse != null)
                        {
                            SemanticLogger.Log.OKTAFileLogInformation("UserInfoResponse received from OKTA : " + System.Text.Json.JsonSerializer.Serialize(userInfoResponse) + Environment.NewLine);
                            claims.AddRange(userInfoResponse.Claims);
                        }
                        else {
                            SemanticLogger.Log.Information("UserInfoResponse not received from OKTA");
                            SemanticLogger.Log.OKTAFileLogInformation("UserInfoResponse not received from OKTA : " + Environment.NewLine);
                        }
                        claims.Add(new Claim("id_token", tokenResponse.IdentityToken));
                        claims.Add(new Claim("access_token", tokenResponse.AccessToken));

                        if (!string.IsNullOrEmpty(tokenResponse.RefreshToken))
                        {
                            claims.Add(new Claim("refresh_token", tokenResponse.RefreshToken));
                        }

                        n.AuthenticationTicket.Identity.AddClaims(claims);
                        SemanticLogger.Log.OKTAFileLogInformation("Claims created using Token/UserInfo Responses from OKTA : " + string.Join("\t", claims) + Environment.NewLine);
                    }
                    else
                    {
                        SemanticLogger.Log.Information("TokenResponse not received from OKTA ");
                        SemanticLogger.Log.OKTAFileLogInformation("TokenResponse not received from OKTA : " + Environment.NewLine);
                    }

                    return;
                },

                RedirectToIdentityProvider = n =>
                {
                    // If signing out, add the id_token_hint
                    if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                    {
                        var idTokenClaim = n.OwinContext.Authentication.User.FindFirst("id_token");

                        if (idTokenClaim != null)
                        {
                            n.ProtocolMessage.IdTokenHint = idTokenClaim.Value;
                        }

                    }

                    return Task.CompletedTask;
                }
            },
        });

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/WipLogin/RedirectURL")
        });

    }
}

}

The login method code as below
if (!HttpContext.User.Identity.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);

                return new ContentResult();

            }

Please help here

Can you please open a support case with us at developers@okta.com in order to have one of our Developer Support Engineers further assist you?

Do the same set of users encounter this issue, or does it happen sporadically for any user? Are any requests or redirects looping? If so, to which endpoints/routes?

Have you added any logging or breakpoints into your application to try to narrow down the issue and/or see if any errors are being thrown? For example, is IsAuthenticated coming back as false when this behavior occurs? If so, you may want to check out these posts about issues with OWIN cookies in .NET (not Core):

Also, do you ever encounter an error about the Headers being too large? I’ve seen that occur during redirect loops in .NET before as well.

2 Likes