Bug 21586 - Add generic OpenIDConnect client implementation
Summary: Add generic OpenIDConnect client implementation
Status: RESOLVED DUPLICATE of bug 30988
Alias: None
Product: Koha
Classification: Unclassified
Component: Authentication (show other bugs)
Version: Main
Hardware: All All
: P5 - low enhancement (vote)
Assignee: David Cook
QA Contact: Testopia
URL:
Keywords:
: 3237 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-10-17 07:59 UTC by David Cook
Modified: 2022-06-24 00:35 UTC (History)
7 users (show)

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


Attachments
Bug 21586: Add generic OpenIDConnect client implementation (46.55 KB, patch)
2018-10-17 08:45 UTC, David Cook
Details | Diff | Splinter Review
Local login plus external login (19.15 KB, image/png)
2020-01-22 01:27 UTC, David Cook
Details

Note You need to log in before you can comment on or make changes to this bug.
Description David Cook 2018-10-17 07:59:09 UTC
It would be great to have a generic OpenIDConnect client that anyone could point at any OpenIDConnect server for authentication.

Years ago, I wrote this software client for a client that needed to connect to 2 different upstream servers. 

More recently, I've re-used the code for a different client with a different upstream server.

The first third-party server wasn't compliant to the standard, so there are some hacks in my code, but the second latest third-party server does seem compliant, so you should be able to use this code legitimately without compromising as well.
Comment 1 David Cook 2018-10-17 08:45:18 UTC
Created attachment 80689 [details] [review]
Bug 21586: Add generic OpenIDConnect client implementation

BEWARE: This patch is not ready sign off!

This is partially since it exists within Prosentient namespaces,
and partially because a lot of things could probably be improved,
since I originally wrote this code 4 years ago for 1 specific
client.

I'm adding this patch so that others can look at this work,
and either adapt it themselves, or test it and give me feedback
so that I can update it.

I can't guarantee that it works in its current state, as the latest
version I support with this code is 17.05, and I've touched up
a few things here and there that differ from my running code.
Comment 2 David Cook 2018-10-17 08:53:17 UTC
To test:
1) View the =head1 DESCRIPTION in opac/svc/login_openidc. It tells you to write a large chunk of XML into koha-conf.xml. (NOTE: The "prosentient" element is a subling to the "config" element. The only parent to the "prosentient" element is the "yazgfs" element. This is very important.)

2) Configure koha-conf.xml to point to the OpenIDConnect server to which you want to connect. 

3) Change $debugging in opac/svc/login_openidc from 0 to 1. This will help you with your troubleshooting considerably.

4) On your Koha OPAC, using a system preference, add a URL like http://your-koha-host/cgi-bin/koha/svc/login_openidc?pid=foo

5) Click on that link and it should redirect you to a login page for your upstream authentication provider. After you fill that you, you should be returned to your Koha as a logged in user (NOTE: email address is used for matching... if your email address already exists in Koha, you'll be logged in as that user. If your email address doesn't exist, a new user will be created with your details from your upstream provider.)

--

If I've missed anything, comment here or reach me on IRC, and I can provide more details!
Comment 3 David Cook 2018-10-17 08:59:43 UTC
login_openidc is a bit outdated with its POD...

Additional configuration options to consider as children of the "provider" element:

<client_authentication_method>client_secret_post</client_authentication_method>
<bearer_access_token_method>form</bearer_access_token_method>
<logout_url>https://provider/openidconnect/destroy_session</logout_url>

Another optional child of the "mapping" element:

<koha_sort1>company_name</koha_sort1>

(I added this since OpenIDConnect technically allows providers to provide non-typical claims too. This could use a better mechanism for configuration.)
Comment 4 David Cook 2018-10-17 23:55:22 UTC
Comment on attachment 80689 [details] [review]
Bug 21586: Add generic OpenIDConnect client implementation

Review of attachment 80689 [details] [review]:
-----------------------------------------------------------------

::: C4/Auth.pm
@@ +1789,4 @@
>      }
>      else {
>          # catch all defaults to tmp should work on all systems
> +        my $dir = C4::Context::temporary_directory();

Ooops. This was a local fix that I did so that C4::Auth would compile for my client side git hook...I should take that out.
Comment 5 David Cook 2018-11-06 03:31:05 UTC
I've recently been looking at Keycloak https://www.keycloak.org and I'm thinking it could be something that we use for testing this.
Comment 6 David Cook 2019-01-24 04:33:15 UTC
Happy for other people to work on this. This isn't really a priority for me at the moment, although it would be a great addition to Koha!
Comment 7 Katrin Fischer 2019-05-06 05:24:39 UTC
*** Bug 3237 has been marked as a duplicate of this bug. ***
Comment 8 David Cook 2020-01-21 07:00:08 UTC
This code is out of date, and has a few known problems. However, I have a newer version, which I actually have working with the Keycloak OpenID Connect Identity Provider.

For testing purposes, I very easily ran up an instance in Docker (https://hub.docker.com/r/jboss/keycloak/), and after resolving a bug in my code, I was able to successfully authenticate and auto-add a patron to Koha. 

It's worth noting that I have used Keycloak for other projects for a while now, so the server configuration was trivial for me, but it might not be obvious at a glance. There is lots of documentation though. 

Might also be worth noting that Keycloak is sponsored by Red Hat and forms the core of RH-SSO, which Red Hat actually uses for all its own AuthN purposes. 

Note that even though I have a new version of the code that works, I'd actually like to redo my code for this one.
Comment 9 David Cook 2020-01-21 07:11:50 UTC
Actually, this one would be great to add as an "Authentication Plugin" for Koha. 

Looking at my code, the only part of it which doesn't lend itself to a plugin architecture are the changes to Auth.pm and opac-auth.tt. 

However, we could probably remove the necessity for opac-auth.tt changes.

And we could add hooks into Auth.pm for login and logout. Looking at my code, those shouldn't be that hard to add. 

--

One of the interesting things with this work was setting up multiple OpenID Connect providers. I'm not sure how often that would actually be a requirement (as I think people sometimes use another IdP to federate others together) but it was originally a requirement for my work, and it's something I've seen other people ask for online. 

--

Really we should be able to use OpenID Connect against Google and any other compliant IdP (like Keycloak).
Comment 10 David Cook 2020-01-21 07:12:47 UTC
I don't have plans to work on this at present, but it is an interest of mine, so if I find myself with spare time, I would work on it (although the OAI-PMH harvester is a competing albeit much more complex interest).
Comment 11 David Cook 2020-01-22 01:27:00 UTC
Created attachment 97684 [details]
Local login plus external login

Example of local login plus external logins.

The links/buttons are for URLs like this:

https://gitlab.com/users/auth/google_oauth2
https://gitlab.com/users/auth/twitter

It would be interesting to have plugins so that we could do things like:

https://koha/users/auth/google
https://koha/users/auth/custom_idp1
https://koha/users/auth/custom_idp2
Comment 12 David Cook 2020-01-30 07:40:28 UTC
I decided to make some strides on generic authentication and opened https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=24539

I've refactored my OpenID Connect code to take advantage of a standard generic interface in Auth.pm and opac-auth.tt. 

I still have some work to do on the endpoint that triggers the login, but I have some ideas about that.
Comment 13 Michal Denar 2020-01-30 10:20:17 UTC
Great news, David.
Comment 14 David Cook 2022-06-21 00:32:20 UTC

*** This bug has been marked as a duplicate of bug 30988 ***
Comment 15 David Cook 2022-06-21 00:36:57 UTC
While this patch has more functionality than bug 30988, it was originally written for a buggy OIDC IdP 8 years ago and it's outdated in a number of ways. 

While I run a newer local version in prod (and I probably will keep running it locally), I actually want to re-write this functionality using Mojolicious. In fact, there's already a plugin to take care of the majority of it: https://metacpan.org/pod/Mojolicious::Plugin::OAuth2

But I'm not planning on doing that any time soon, so I'm happy to endorse bug 30988 as the replacement for bug 21586, since Shi Yao Wang is actively working on that one.
Comment 16 David Cook 2022-06-24 00:35:27 UTC
Just noting that I've signed off Bug 30988 so it would be great to get some QA eyes on it.