Bug 25796 - Allow REST API to use external OAuth2 authorization server
Summary: Allow REST API to use external OAuth2 authorization server
Status: NEW
Alias: None
Product: Koha
Classification: Unclassified
Component: REST API (show other bugs)
Version: unspecified
Hardware: All All
: P5 - low enhancement (vote)
Assignee: Tomás Cohen Arazi
QA Contact:
URL:
Keywords:
Depends on: 30194
Blocks:
  Show dependency treegraph
 
Reported: 2020-06-18 03:35 UTC by David Cook
Modified: 2024-03-09 12:15 UTC (History)
3 users (show)

See Also:
Change sponsored?: ---
Patch complexity: ---
Documentation contact:
Documentation submission:
Text to go in the release notes:
Version(s) released in:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Cook 2020-06-18 03:35:48 UTC
At the moment, Koha's REST API only validates tokens using the embedded authorization server Net::OAuth2::AuthorizationServer.

It would be great if Koha were configured to use an external authorization server (like Keycloak). 

We could redirect the /token endpoint to Keycloak, or just require consumers to query Keycloak directly for access tokens I suppose.

Then we'd set up Koha to either embed (or more sustainably fetch) Keycloak's public key in order to verify that the access token is coming from Keycloak. We'd then do further token validation (to make sure it's not expired, it's for the correct audience, etc).
Comment 1 David Cook 2020-06-18 03:41:18 UTC
One of the advantages of using an external server like Keycloak would also be that the API would be able to be used with many different grant types and not just client credentials. 

At some point, I'm planning to upstream some work I've done on integrating Keycloak (and any other compliant OpenID Connect Identity Provider) via Bug 21586 for regular end user login. 

For what it's worth, this is a setup I've worked on with other projects. There will be a central identity provider, which can also include authorization information, and all the organisation's applications will use that same central IdP to issues tokens, and then all the applications are configured to consume those signed (JWT) tokens.
Comment 2 David Cook 2022-07-28 04:47:13 UTC
Here's another thought:

If Koha and other applications used Keycloak for SSO, the id_token and refresh token could be saved, and used beyond the initial login.

For instance, a user logs into MyApp, which redirects them to Keycloak and back to MyApp. They click "Place a Hold" on an item in MyApp, which then sends an API request with id_token to Koha. 

Koha takes the id_token and validates it against Keycloak. If it's valid, API request proceeds. If it's invalid, it spits out a 401. 

MyApp could verify the id_token ahead of time or re-try after using the refresh token to get a new id_token. That's irrelevant right now.

--

The only difficulty I have in mind at the moment is... how does Koha know which IdP to query with the id_token? It's easy if your Koha is only set up with one IdP. With more than one, it would be more complicated...
Comment 3 David Cook 2022-07-28 05:09:34 UTC
Unless the Keycloak uses Koha as its backend user storage, I suppose that could circumvent a number of Koha business rules though. That would need to be checked.

Hmm this is interesting:
https://developers.google.com/identity/sign-in/web/backend-auth

In that example, you get the id_token from your SSO IdP, and then you send it to your other backend server (eg. Koha), and then Koha can verify the token (at this point it can create a new user if one is missing, or it can validate an existing user).

Then Koha could return whatever.

Hmm needs more thought.
Comment 4 David Cook 2022-07-28 05:51:51 UTC
But then if you read this: https://auth0.com/blog/id-token-access-token-what-is-the-difference/

In theory, the access token should be for the "Resource server" (ie the Koha API). I suppose that the access token can then be used to do a UserInfo lookup in order to get the user info (I did that in my early 2014 OpenID Connect work).

I suppose the Koha API would check the "iss" and "aud" claims. The "iss" would let it know what IdP to talk to (and whether or not it trusts it). I think the "aud" would need to be the whole Koha API and then further authorization would be handled by Koha at a more granular level...

Looking at Koha::OAuth, it would be fairly trivial to add support. We'd just need a table really to store providers. If the "iss" provider isn't found in the table, then we default to a Koha supplied access token.

We need a table to store providers anyway for improving Koha's SSO options so this dovetail with that.

If we wanted to handle this with plugins, we could do that instead so long as we put a plugin hook in "Koha::OAuth::_verify_access_token_cb". 

It does look like we'd need to alter Koha::Rest::V1::Auth a little bit as it tries to lookup the patron using the "client_id" in the access token. 

Anyway, lots of possibilities there.
Comment 5 David Cook 2022-07-28 23:41:59 UTC
I might actually end up doing this work locally.
Comment 6 Sven 2024-03-09 12:15:14 UTC
Alternatively, it would be possible to support the integration of Apache2 mod_auth_openidc (https://github.com/OpenIDC/mod_auth_openidc) similar to Shibboleth (https://wiki.koha-community.org/wiki/Shibboleth_Configuration).