Open ba1ash opened 3 months ago
Hi, To make user_oidc able to take care of getting new access tokens (with token exchange) to access specific remote services, it should have a new "subscription" mechanism for other apps to ask for it.
It seems easier to perform this token exchange in integration_openproject when getting the login token (when handling the TokenObtainedEvent
event).
Maybe I'm missing your point. Are you saying it's harder to do this in the app receiving the login token rather than directly in user_oidc?
Hi @julien-nc As per my understanding, Yes we can implement the whole case in our app (token handling) but the thing that the above issue point out is the same token handling thing can also might be required for other application (may be later) and those token handling thing would be repeated i guess. In addition to that, also once we get the token we have to refresh it again and again for thebackend to backend
communication. That thing would also be great if it can be possible to be implemented and handled by user_oidc
. In general it would be a feature request in the user_oidc
app.
CC @ba1ash @wielinde @individual-it can also add some thoughts regarding it.
Exactly what @SagarGi wrote. The idea is to centralize functionality in one space that many apps would need in common. Retrieving of tokens, storing of tokens, updating of tokens and exchanging of tokens. Even though each app could build it themselves I believe that we all would be better off centralizing the code.
The piece that would be hard to build into each app is the renewal of the refresh tokens as we cannot be sure that the code of the app is somewhere executed before the refresh token has to be renewed. Better to have that functionality embedded in the OIDC app
Hey there. We don't have the resources in the following months to dive into this. Here are my suggestions:
If you prefer going with 2., here is a rough plan that came to mind:
OCA\UserOIDC\Event\TokenObtainedEvent
event when the ID token + access token + refresh token have been obtained (end of the login flow)OCA\UserOIDC\Event\TokenExchangeRequest
event (with some parameters about the scopes)OCA\UserOIDC\Event\TokenExchangeDone
event which contains an ID for this tokenOCA\UserOIDC\Event\GetExchangedToken
event)
OCA\UserOIDC\Event\GetExchangedToken
.user_oidc/lib/AppInfo/Application.php
, check very often if some of the stored tokens need to be refreshed and refresh them immediatelyWhat do you think?
Suggestion 2 sounds good to me. @julien-nc from your suggestion, i might lack knowledge on what you have mentioned but can't we simply do something like this?
user_oidc
saves ID token + access token + refresh token (which i think it already does). And since this token is of no use for nextcloud (as far as i know since it creates a user session on its own once it has been authenticated) and also for integration_openproject
(the targeted aud
is not set yet) for backend to backend request.user_oidc
built a mechanism to keep access_token
alive since it is used for token exchange for a new token.user_oidc
the token exchange mechanism when Nextcloud
wants a token to have a backend to backend request to OpenProject
through integration_openproject
with a TokenExchangeRequest
event whose information can be save it in our integration app itself (may be).aud
for backend to backend request) and when the token cannot be used anymore we again ask user_oidc
a new token (since the user_oidc
keeps alive the old token so that new token can be obtained through token exchange).I do not know if it is the same thing that @julien-nc has mentioned in suggestion 2.
@individual-it @wielinde @ba1ash
@SagarGi I updated my previous comment with more details.
Reaction to your last comment:
OCA\UserOIDC\Event\TokenObtainedEvent
which contains themI hope that makes it clearer. It's just my recommendation on how to implement this. Feel free to suggest other approaches.
@julien-nc Thanks for the reaction. The updated comment of yours is more clearer. And it seems to be doable.
@julien-nc here is the proposed flow chart: token_handling.pdf
As just discussed, we can also use the event system to call into the user_oidc
app
Ever more often Nextcloud is bundled with other applications, such as OpenProject, sharing one user session across the integrated applications via OIDC single sign on (SSO).
For deep integrations Nextcloud apps need to be able to make impersonated back-end to back-end API requests to bundled applications.
Up until now the impersonation was often achieved via OAuth2 flows, which has an inferior UX as it is pretty complex for user to understand. It requires involvement of the user. And the cognitive load often is too high. They fail. A better approach would be to use the trusted OIDC provider to hand out access tokens during SSO that then can be used to authorize requests to bundled applications. Then the user only needs to login and no further actions by the user are necessary.
We believe that
user_oidc
would be the ideal place for managing the access tokens. It has all the setup/configuration information needed to interact with the OIDC provider. Further it already receives the ID, access and refresh tokens.As developers of OpenProject Integration app we would like to have access to the access token with sufficient privileges to use it for authorizing outgoing requests to the OpenProject server. By sufficient privileges we mean, for instance, presence of OpenProject server client_id in
aud
claim of the access token and required scopes inscope
claim. We see two possible scenarios how to get such a token:OIDC provider is configured to add OpenProject client_id to
aud
claim for access token issued to Nextcloud client_id.OIDC provider is configured to support token_exchange. Then the original access token can be exchanged for another one exclusively used to access OpenProject (having only the OpenProject client_id in the
aud
claim).Then the access to this access token could be given to other Nextcloud applications,
integration_openproject
among them, as an event subscription or in any different way.Besides that the following cases should be taken into consideration:
access token has been expired. In this case we need a way to get a fresh access token.
refresh token has been expired. Probably, it means user has to renew its session.
We are not sure about the exact API that could be provided to cover these scenarios.
Kindly let us know if what we ask is possible to achieve.
@julien-nc @wielinde @SagarGi