DuendeSoftware / Support

Support for Duende Software products
21 stars 0 forks source link

Question regarding Cookie Expiration in Legacy MVC and WebAPI based App. #1058

Closed nigelbasel closed 9 months ago

nigelbasel commented 9 months ago

Which version of Duende IdentityServer are you using? 6.2.3 Which version of .NET are you using? .NET Framework 4.7.2 Client, .NET 7 Identity Server

Question

We have a Legacy .NET Framework ASP.NET MVC/Win Forms Application which we have ported to use Identity Server. The Application Makes AJAX calls to WebAPI Controllers on some of its pages. Once the User Cookie expires, normal pages redirect to the authorization endpoint on Identity Server and the cookie is refreshed. If the cookie expires and a page makes a call to one of the WebAPI controllers, the runtime attempts to redirect to the authorize endpoint, which fails. We understand that this is not the correct model, and that we should be returning a 401 from the api call in this case, but what is not clear is exactly what the front end should then do in response to that 401. We have also considered changing all the api calls to user bearer token authentication, which does work, but are unsure of best practice in regard to refreshing and storing this token.

Some guidance would be appreciated.

josephdecock commented 9 months ago

Our recommendation is for the front end to not ever handle tokens directly, and only use the cookie as you are doing now.

When the access token stored in the session expires, the typical way to get a new token is to use a refresh token to make a new token request. The resulting new token should be added to the session and a new session cookie issued.

Our sample implementation here shows how this is done in .NET framework.

nigelbasel commented 9 months ago

Hi Joseph, thanks for the reply. I have been using that exact sample to try and resolve this issue. The problem we have is when the cookie itself expires, which is why we were considering storing the bearer token on the client. Consider the scenario a user leaves the browser alone for longer than 20 minutes (the default timeout for the asp.net session cookie). If they then return to the browser and carry out an action that results in an ajax call, the middleware will then attempt to redirect the XHR call to the authorize endpoint. The guidance I have previously seen suggests overriding the RedirectToIdentityProvider event to respond with a 401 instead of the 302 to redirect to authorize, which I am able to do. The problem now is what to do on the client to cause a new cookie to be issued so that we can retry the api?

Once again, thanks for the response.

josephdecock commented 9 months ago

In the javascript that makes the XHR you can detect 401 errors and then take action.

To get a new token, you need to initiate a new challenge, and the easiest way to do that is probably to simply refresh the page. Assuming the page requires authentication, that will start the OIDC handshake.

Depending on what your users have been doing before the 401, you might want to consider the user experience before redirecting. For example, if the user has entered a lot of information, it can be a good idea to save that information temporarily within browser storage, and then notify the user with something like "You've been logged out, but this info has been saved. Press continue to reenter your credentials", and then give them a button that would refresh, rather than just doing it instantly when you see 401. Then when you load the page, have some javascript return them to their previous state via the browser storage, and clear it out. (Of course, think carefully about the sensitivity of the data that you're storing in the browser as well!)

nigelbasel commented 9 months ago

Hi Again Joseph, thanks for the response. That makes perfect sense, we will follow your guidance.