JanssenProject / jans

An open source enterprise digital identity platform for CIAM or workforce... Janssen is a distribution of standards-based, developer friendly, components that are engineered to work together in any cloud. #OAuth #OpenID #FIDO
https://docs.jans.io
Apache License 2.0
457 stars 74 forks source link

fix(jans-auth-server): missing session in db cause failure in authentication #4385

Closed SafinWasi closed 1 year ago

SafinWasi commented 1 year ago

Describe the bug After the user has authenticated with the auth server, the session cookies may be cleaned from db after a period of time. If the cookies are still present in browser, the auth server fails to authenticate and throws a ifUserIsNull exception. Full stack trace is described below.

To Reproduce Steps to reproduce the behavior:

  1. The most recent behavior of this can be observed via the Agama Developer Studio. Visit https://cloud.gluu.org/agama-lab and login via GitHub.
  2. Either clean cookies manually or wait for them to be removed from db. Observed timing behavior has varied. @nynymike has reported that logging in the next day causes the error.
  3. Try to authenticate again. Jans will throw an error.

Expected behavior The auth server should handle reauthentication properly.

Screenshots image

Desktop (please complete the following information):

Additional context The full exception is such:

jakarta.ws.rs.WebApplicationException: HTTP 302 Found
    at io.jans.as.server.authorize.ws.rs.AuthorizeRestWebServiceImpl.ifUserIsNull(AuthorizeRestWebServiceImpl.java:731) ~[classes/:?]
    at io.jans.as.server.authorize.ws.rs.AuthorizeRestWebServiceImpl.authorize(AuthorizeRestWebServiceImpl.java:346) ~[classes/:?]
    at io.jans.as.server.authorize.ws.rs.AuthorizeRestWebServiceImpl.requestAuthorization(AuthorizeRestWebServiceImpl.java:262) ~[classes/:?]
    at io.jans.as.server.authorize.ws.rs.AuthorizeRestWebServiceImpl.requestAuthorizationGet(AuthorizeRestWebServiceImpl.java:203) ~[classes/:?]
    at io.jans.as.server.authorize.ws.rs.AuthorizeRestWebServiceImpl$Proxy$_$$_WeldClientProxy.requestAuthorizationGet(Unknown Source) ~[classes/:?]
    at jdk.internal.reflect.GeneratedMethodAccessor497.invoke(Unknown Source) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:?]
...
yuriyz commented 1 year ago

When PersonAuthenticationType script is run AS stores data in session. So flipping steps, as well as parameters are bound to session (unauthenticated). On AS we have configuration "sessionIdUnauthenticatedUnusedLifetime":120. After 2 minutes of inactivity session is considered as invalid and can be cleaned up.

Immediate actions should be:

  1. Set sessionIdUnauthenticatedUnusedLifetime to 1 hour by default: 3600 (or maybe even higher number). This step will help to get less frustration from end-user to re-enter credentials. However still user can pass step 1, go for lunch and return back in 2 hours and session will be cleaned up. Means this step alone does not solve problem. To solve it we need to check session existance in custom script.
  2. In custom script before normal script execution continues, check whether session exists. If it does not exist, re-initiate call to Authorization Endpoint to start from beginning.
def prepareForStep(self, configurationAttributes, requestParameters, step):
    sessionIdService = CdiUtil.bean(SessionIdService)
    sessionId = sessionIdService.getSessionId()
    if (sessionId == None):
        # redirect directly to Authorization Endpoint or otherwise to RP to re-initiate authorization request
        facesService.redirectToExternalURL(redirect_to_authorization)

Long term plan

  1. increase sessionIdUnauthenticatedUnusedLifetime (in setup).
  2. add check whether session exists in custom script.
  3. add cookie to redirect back to RP with error session_expired
  4. add default error page if nothing above didn’t work (unplanned error)
yuriyz commented 1 year ago

@SafinWasi please add check as described above to github custom script.

yuriyz commented 1 year ago

Closing this ticket as solved. 1 and 2 are done. For 3 and 4 opened separate development ticket https://github.com/JanssenProject/jans/issues/4449

  1. increase sessionIdUnauthenticatedUnusedLifetime (in setup). Done in https://github.com/JanssenProject/jans/pull/4446
  2. add check whether session exists in custom script. Done in github script by Safin.
  3. add cookie to redirect back to RP with error session_expired
  4. add default error page if nothing above didn’t work (unplanned error)