OIDC login from mobile app fails when using Okta as external IDP

I’m using Okta as an external IDP with IdentityServer 3 (legacy software, I know). I’ve used IdentityServer 3 with other OIDC clients and they’ve all worked correctly. Okta works correctly when the user is logging in from our website, using the hybrid flow with an Okta OIDC client. When logging in from the mobile app (hitting identityserver within an in-app browser, then hitting external Okta login) from a similarly set up client, the login fails.

After some investigation, Okta correctly passes back the code/tokens but it seems that the signin id may not be getting passed back from Okta when hitting /core/callback endpoint. This causes a log from IdentityServer (or .NET itself) saying: “no signin id passed” before redirecting to an error page which says “There is an error determining which application you are signing into. Return to the application and try again.” I’m reasonably sure this is an issue with Okta because we have used the exact same configuration with other OIDC external IDPs before with mobile apps and it’s worked flawlessly.

Here’s my configuration code, if it’s helpful:

in Clients.cs of IdentityServer:

 new Client
 {
     Enabled = true,
     ClientName = "REDACTEDCLIENTNAME",
     ClientId = "REDACTEDCLIENTID",
     Flow = Flows.HybridWithProofKey,
     AllowedScopes = new List<string>
     {
         Constants.StandardScopes.OpenId,
         Constants.StandardScopes.Profile,
         Constants.StandardScopes.Email,
         Constants.StandardScopes.Roles,
         Constants.StandardScopes.OfflineAccess,
         "REDACTEDService",
         "REDACTEDClientService"
     },
     IdentityTokenLifetime = FourteenDays,
     AccessTokenLifetime = FourteenDays,
     ClientUri = "https://REDACTED.com",
     RequireConsent = false,
     AllowRememberConsent = true,
     RedirectUris = new List<string>
     {
         "REDACTEDAPP://",
         "https://REDACTEDIDENTITYSERVER.com/core/", // Testing, this wasn't needed with other mobile clients
         "https://REDACTEDIDENTITYSERVER.com/core/callback", // Testing, this wasn't needed with other mobile clients
     },
     PostLogoutRedirectUris = new List<string>
     {
         "REDACTEDAPP://"
     },
     ClientSecrets = new List<Secret> {
         new Secret("REDACTEDSECRET".Sha256())
     }
 },

And in Startup.cs of IdentityServer:

 app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions("TestOkta")
 {
     Authority = "https://dev-REDACTED.okta.com/oauth2/default",
     ClientId = "REDACTEDCLIENTID,
     ClientSecret = "REDACTEDSECRET",
     RedirectUri = "https://REDACTEDIdentityServer/core", 
     ResponseType = "code id_token",
     Scope = "openid profile email offline_access",
     Caption = "TestOkta",
     SignInAsAuthenticationType = "Cookies",
     UseTokenLifetime = false,
     TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
     {
         NameClaimType = "name",
         ValidIssuer = "https://dev-REDACTED.okta.com/oauth2/default",
         ValidateIssuer = true
     },
     MetadataAddress = "https://dev-REDACTED.okta.com/oauth2/default/.well-known/openid-configuration",
     Notifications = new OpenIdConnectAuthenticationNotifications
     {
         RedirectToIdentityProvider = n =>
         {
             // Get id hint from owin context and add to protocol message
             // if signing out, add the id_token_hint
             if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Logout)
             {
                 var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
                 if (idTokenHint != null)
                 {
                     n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                 }
                 // Okta does not support post logout redirect uri with dynamic id params, so remove it
                 if (n.ProtocolMessage.IssuerAddress.Contains("okta"))
                 {
                     n.ProtocolMessage.PostLogoutRedirectUri = null;
                 }
             }
             return Task.FromResult(0);
         },
         SecurityTokenValidated = (context) =>
         {
             // Add ID token as new claim to the identity, to be used on logout for OIDC id_token_hint
             var token = context.ProtocolMessage.IdToken;
             context.AuthenticationTicket.Identity.AddClaim(new System.Security.Claims.Claim("id_token", token));
             return Task.FromResult(0);
         }
     }
 });

I forgot to mention that the normal flow for the other OIDC clients on the mobile app is:

  1. Open in-app browser to identityserver
  2. Click the external login
  3. Log in to the external IDP (in this case, Okta)
  4. External IDP posts to callback URL with tokens embedded in post
  5. Mobile app extracts tokens from callback page

The issue here is in step 4, where the Okta instance does not include the signin id needed when posting to callback URL with tokens.

Hi,

As for the no signin id passed, did you already looked into this post?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.