Login Challenge in case of sharing / reusing login page link

Hi folks,

We have a question related to login challenge code. Login challenge is passing in front channel communication and users can share the link with code challenge between each other, bookmark login page in browser or do other crazy things.

It creates sometimes weird situation that users reusing challenge codes accidentally. For example today we got a case when user logged in successfully with code_challenge but saved link, opened it again after some time, passed login flow and we got pq: duplicate key value violates unique constraint "hydra_oauth2_authentication_request_handled_pkey" exception when backend tried to accept the challenge.

Is it any practices or workarounds what to do with situation when users authenticated successfully in app but login challenge is stale / expired? What app should do in this case?

btw when we played with code today we got a feeling that CHALLENGE_TOKEN_LIFESPAN (ChallengeTokenLifespan in config) is not used in code. can you please point where ChallengeTokenLifespan is checked?

The duplicate acceptance of a challenge is really dangerous which is why an error is shown. I do agree though that the error message could be improved, feel free to create an issue and/or PR!

Regarding the lifespan, it’s indeed hardcoded at the moment to time.Minute*15. This can easily be fixed though, please create an issue and/or PR!

Can you comment about the what login app should do in this case?

User can create situation when they opened login page with already used code challenge (history, sharing, bookmark). It’s in front-end channel and it’s a GET request so user can get url and reuse it. Right now hydra always returns the information in /oauth2/auth/requests/login/{challenge} when we asked about login challenge (even after lifespan, even if it was already used) and we continue login flow even if challenge can not be accepted later.

The main issue that we show login flow, user spends time to fill it it but we don’t have an ability to accept user login at the end on hydra side and don’t have a good behaviour to not loose user input. Login application knows that user is authentication and user knows that credentials is right but still see error.

Oh I see, so what you’re suggesting is that /oauth2/auth/requests/login/{challenge} should already return an error if the challenge has been used already, right? That makes total sense (please track it in an issue on GH, thank you!)

Once that is done: The login app should show an error and a way to e.g. go back to the home page or whatever!

Hi, was this ever resolved fully? I see related issue was resolved in GH (https://github.com/ory/hydra/pull/1098). However I notice one of the commits says (SQL Only). Does that mean this was only resolved for SQL server? We’re currently using ORY Hydra 1.2.0 and mySQL as our DB and we seem to be encountering the same issue described by the OP but slightly different.

Instead of reusing a login challenge, we have a login challenge that was never used but its expired. We hit that request login endpoint GET /oauth2/auth/requests/login/{challenge}, it’s responding with 200. If we continue the flow, user authenticates then we hit the accept login endpoint (PUT /oauth2/auth/requests/login/accept/{challenge}), it still returns 200. However, on redirecting to the login verifications step, that’s where it fails and ORY Hydra redirects to the RP callback endpoint.

What’s the recommended practice to handle unused/expired challenges? Should we just redirect from the RP callback and restart the login flow?

Please upgrade to Hydra 1.4 or 1.5