Hello Explosion team,
We are working on a web application for a customer, which integrates Prodigy for 5 users using Prodigy company license and the Prodigy company plugins. Prodigy is installed into a dedicated virtual environment and started/stopped via a subprocess. The main web application and Prodigy shall use OpenID Connect against Keycloak. Both applications get their own subdomain using an Nginx reverse proxy.
Like some other user(s) in the forum (Bug Report: Call to get_session_questions fails with 403 Unauthorized,) we also encountered the problem of a response 403 Forbidden for /get_session_questions (or give_answers on saving using the save button):
{
"error": "Unauthorized",
"detail": "No token provided. Not authenticated.\n"
}
This error message is caused by no Prodigy authentication cookies present, because they have expired.
Normally there is a cookie __prodigy_cauth_id_token__ and a cookie __prodigy_cauth_access_token__.
It can be temporarily resolved by refreshing the page, but that loses existing annotations that were not transmitted to the backend, yet.
I was able to determine that this recurring problem is strictly coupled to the Access Token Lifespan configured in Keycloak. This value defaults to 1 minute and should be kept at a low value.
So, after one minute or more of idling or annotating without a backend request, the problem occurs. If it takes less than a minute it remains fine. The same I could reproduce for an Access Token Lifespan of e.g. 15 minutes where 14 minutes are fine, but 15 minutes or more cause the error.
In the implementation of the authentication in the Prodigy company plugins source code there is a method ProdigyCompanyAuth.get_tokens_from_auth_code. This returns a UserTokensResponse created from only a small subset of the authentication response payload.
{'access_token': '<ACCESS_TOKEN>', 'expires_in': 60, 'refresh_expires_in': 1800, 'refresh_token': '<REFRESH_TOKEN>', 'token_type': 'Bearer', 'id_token': '<ID_TOKEN>', 'not-before-policy': 0, 'session_state': '<SESSION_STATE>', 'scope': 'openid email profile'}
Of these fields only id_token, access_token, expires_in and token_type are used.
Then the short expires_in value for the access_token is used for both the access token and the ID token cookies as expiration duration.
However the longer lived refresh token is not used at all and discarded. I am not an authentication expert myself, but I found out that usually a refresh token is used to get a new access token when necessary.
Can you give recommendations on how we can mitigate the issue or improve the OIDC plugin?