Context Authentication Ticket is null

I have a web application using .net/Owin middleware/OpenIdConnect. The app is configured as a web application in Okta with grant type as “Authorization Code”. I can authenticate and get the token response, but when I try to add the claim to the authentication ticket, I get an exception that the authentication ticket is null in the following line.

n.AuthenticationTicket.Identity.AddClaims(claims)

If I allow “Implicit (hybrid)” in the set up, and change the responsetype to “CodeIdToken”, the above code works fine. I just want to make this work with “authorization code” grant type since from what I read, implicit hybrid is not recommended for web apps.

Here is my code. Am I missing something?

 public void ConfigureAuth(IAppBuilder app)
   {
       app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
       app.UseCookieAuthentication(new CookieAuthenticationOptions
       {
           CookieManager = new SystemWebCookieManager()
       });
       app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
       {
           Authority = _authority,
           ClientId = _clientId,
           ClientSecret = _clientSecret,
           RedirectUri = _redirectUri,
           PostLogoutRedirectUri = _postLogoutRedirectUri,
           ResponseType = OpenIdConnectResponseType.Code,
           Scope = "openid profile email",
           TokenValidationParameters = new TokenValidationParameters
           {
               NameClaimType = "name"
           },
           UsePkce = false,
           Notifications = new OpenIdConnectAuthenticationNotifications
           {
               SecurityTokenValidated = (context) =>
               {
                   var name = context.AuthenticationTicket.Identity.FindFirst("preferred_username").Value;
                   context.AuthenticationTicket.Identity.AddClaim(new Claim(ClaimTypes.Name, name, string.Empty));
                   return Task.FromResult(0);
               },
              
               AuthenticationFailed = OnAuthenticationFailed,
               AuthorizationCodeReceived = async n =>
               {
                   // Exchange code for access and ID tokens
                   var client = new HttpClient();
                   var tokenResponse = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
                   {
                       Address = $"{_authority}/v1/token",
                       ClientId = _clientId,
                       ClientSecret = _clientSecret,
                       Code = n.Code,
                       RedirectUri = _redirectUri
                   });

                   if (tokenResponse.IsError)
                   {
                       throw new Exception(tokenResponse.Error);
                   }

                   var userInfoResponse = await client.GetUserInfoAsync(new UserInfoRequest
                   {
                       Address = $"{_authority}/v1/userinfo",
                       Token = tokenResponse.AccessToken
                   });
                  
                   var claims = new List<Claim>();
                   claims.AddRange(userInfoResponse.Claims);
                   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);// This is where it fails

                   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;
               }
           }
       });

   }

Thanks!

Hello @jayanthy.kapistalam,
Thank you for reaching out here on the Okta Developer Forum.

It looks like you are using an old version of .NET and OWIN and it appears that the authorization code grant type might not be fully supported in this case.

The recommendation would be to use a new version of .NET and OWIN.

Hi, thanks for the pointer. OpenIdConnect authentication middleware does not support auth code grant type without implicit hybrid for .net frame work 4.8, but we are not ready to migrate it to .net core as of yet. I was able to address this issue by changing it to use OktaMvc and it works for both options. Here is the code, hope this helps someone.

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                CookieManager = new SystemWebCookieManager(),
                CookieSameSite = SameSiteMode.Lax,
                CookieSecure = CookieSecureOption.Always,
                LoginPath = new PathString("/Account/Login")
            });
            app.UseOktaMvc(new OktaMvcOptions
                {
                    OktaDomain = _domain,
                    ClientId = _clientId,
                    ClientSecret = _clientSecret,
                    AuthorizationServerId = _authServer,
                    RedirectUri = _redirectUri,
                    PostLogoutRedirectUri = _postLogoutRedirectUri,
                    Scope = new List<string> { "openid", "profile", "email" },
                    LoginMode = LoginMode.SelfHosted,
                    OpenIdConnectEvents = new OpenIdConnectAuthenticationNotifications
                    {
                        AuthenticationFailed = OnAuthenticationFailed
                    }
                }
            );
1 Like

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