Password prompt after 60 minutes

We are in the process of implementing SSO with OIDC in several of our ASP.Net Core and ASP.Net MVC 5 (.Net Framework 4.8) applications, using the Okta-hosted redirect method. We have based our implementations on the sample applications provided and are using the Nuget packages supplied by Okta.

When an application session starts up, it starts the SSO handshake by calling authorize?client_id=XXX… the browser flashes through a sequence of images and messages, eventually loading the application as requested with no additional user actions required.

All applications behave normally for the first hour. When browsing the .Net Core applications, once one hour of time has elapsed the network traffic in the developer tools appears unaffected, i.e. the same session ID and cookie continue to be passed on each request and there is no further attempt to authenticate, provided the user’s ASP.Net 60 minute session has not expired and /or the Signout has not been called.

Conversely, in the .Net Framework applications, when one hour of time has elapsed, a page navigation shows in the developer tools that the authorize sequence is restarted, it proceeds through a series of “Probes” trying to contact various localhost ports, and then gives up and redirects to Okta password entry page, while still displaying the identity of the user. If I do a client-side call after 1 hour, such as refreshing a Kendo grid, a CORS exception is logged in the developer tools. Obviously neither of these scenarios is what we want or expect, we want the user to seamlessly and continuously be able to navigate the application as long as their ASP.Net session has not expired.

It seems as though the Core applications are doing some sort of “sliding expiration” that allows them to forgo the re-authorization process, but whatever is happening there does not occur in the Framework applications. I have tried various settings with UseCookieAuthentication and UseOktaMvc, but nothing changes, including with the sample application. The Okta cookie size is significantly larger in .Net Core, such that it is chunked into two cookies. The app session expiration based Signout occurs as expected and redirects the user to our Signout page. Signing back in from this page usually, but not always, works as expected, i.e. the normal handshake described above happens correctly, without additional user intervention.

I do not have access to the admin console (it is fiercely protected by the team that “owns” it), but I am assured that ALL of the applications are configured the same (and ostensibly correctly). So does this sound like a configuration issue in the admin console or the application, or do we need to manually implement something in the Framework apps to emulate what is done out-of-the-box in .Net Core? If we need to do a manual refresh, can someone refer me to a sample implementation? I have seen discussion of this elsewhere, but it does not seem to apply to the Okta-hosted redirect method.

We did not identify this problem as repeatable when doing the initial implementation and extensive testing several months ago, only recently did it appear or at least we only recently understood how to reproduce it reliably.

This looks like an interesting problem. I am not sure I have the whole picture (even given the length) because you say you are getting a CORS error and that will only happen if you have a client-side application; .NET Framework or Core does not depend on CORS. So I am going to make several suggestions to proceed. 1) verify there is no client-side authorization, 2) verify the applications are configured as web applications in Okta (hard, I know), and 3) set up a test sandbox (you can get a free Okta developer tenant) and we can look closer at what is going on. Most importantly get to the logs on the Okta side.

Okta can set two cookies, one is a “sid” and the other is “idx”. The idx cookie carries Okta session data.

Thank you for your reply. These are .Net Framework or .Net Core web applications. They contain components such as the Kendo UI grid control, which are rendered server-side but make their data requests from the client via xhr.

I get how the grid works. The description you are giving is confusing though, and I’m making assumptions that I don’t like. Neither the framework or core SDKs have a client-side component, they only make authorization requests from the server. No CORS. So it isn’t either SDK that is introducing this. I’m guessing that you have two different software architectures for the framework and core applications that the software engineers built.

The core application may be doing it the right way. It probably gets the access token during the server-side authorization requests and passes it with the JavaScript for the grid. Then uses JavaScript to ask the page source to refresh the access token if it expires.

The framework application sounds like it is setting up the SPA with the JS SDK to make its own authorization request for a token when it expires. If that is true then a CORS error is simply that the SPA is not registered in the Okta tenant for CORS. The URL the SPA was loaded from needs to be set at Security → API → Trusted Origins.

Either way, this is in the guts of your applications, not in the Okta SDKs. Sorry about that :frowning:

There were two issues at work that motivated this post: the immediate symptom of the unwanted password prompt, which was a side-effect of the larger problem of Okta session expiration.

The Okta MVC 5 sample:

https://github.com/okta/samples-aspnet/blob/master/okta-hosted-login/okta-aspnet-mvc-example/Controllers/AccountController.cs

uses the wrong overload of the HttpContext.GetOwinContext().Authentication.Challenge method. This sample MVC5 implementation ALWAYS causes this password prompt to occur when 60 minutes have elapsed and a web request is attempted.

The correct overload to prevent this behavior was found in the WebForms sample here:

https://github.com/okta/samples-aspnet-webforms/blob/master/okta-hosted-login/okta-aspnet-webforms-example/Site.Master.cs

I added a couple of the other optional properties that were available and the password prompt issue was resolved.

The larger issue though, was why was the session expiring in this way to begin with? The ASP.Net Core applications, with virtually identical configuration, somehow manage to extend the Okta Session expiration time, even without requesting the “offline_access” scope or implementing a refresh token mechanism.

I cannot imagine any real-world scenario in which it would be desirable to have a hard session expiration while a user was actively using an application, i.e. they post a page or try to navigate and instead of the requested action happening, they are redirected to the Okta hosted page, are reauthenticated, then returned to the redirect URL, having lost all of their work and context.

Nonetheless, the MVC Sample cited above makes no mention of, and certainly provides no sample implementation of, building a token refresh mechanism for .Net Framework. Nor did the website documentation for ASP.Net Okta-Hosted, when the links were not broken, do so either. When we opened our Okta support case, the support engineer, who was very earnest and sincerely tried to help, speculated that the tokens weren’t being refreshed for some reason, but readily admitted that they were not very familiar with .Net.

By pure luck, I happened to stumble upon this Github document:

https://github.com/okta/okta-aspnet/blob/master/docs/refresh-token.md?plain=1

that describes a customer-created implementation of token refresh. I was able to adapt this code to my application, add “offline_access” to my scope, and have our infrastructure admin enable the refresh token grant in our admin console configuration and then token refresh started working. I also adapted the Claims Viewer page from the Okta MVC 5 sample, which did assist with troubleshooting and monitoring the details of our session, which were encrypted within the session cookie.

All of this to say, I am incredibly disappointed with this mediocre demoware that provides samples that work, after a fashion, but are nowhere near ready for an enterprise PROD environment, and in which the clues for getting to ready are scattered across the far reaches of Okta’s online presence. Even before getting to this point we faced a number of other challenges getting multiple discrete applications hosted on the same domain to behave properly and to not impact each other, another situation lacking documentation and to which we were left entirely to our own devices.

I realize that .Net Framework 4.8 is an older platform, but it is officially supported by MS indefinitely, so it’s not going away anytime soon. Maybe you should revisit your samples and documentation to provide usable guidance in one place. Rewriting complex, high-volume enterprise applications for technical debt is not something that is always easily done by your customers, especially for very lean teams with stakeholders who constantly demand new features and don’t care about engineering needs.

Okta can take these comments as constructive criticism or ignore it as a rant, but I think my company of 50000 employees, almost certainly spending seven figures per year for licensing and support, deserves better service and support than this, not to mention all of your smaller customers whose size makes them easier to dismiss.

Also there’s a bug in your latest NuGet packages that has been sitting for two weeks without response, we had to downgrade to 3.2.4 and 5.1.1 to avoid.

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