Authenticating Nextcloud with Keycloak using OpenID Connect

A few months ago I started over on my home server with a fresh install of CentOS 7.6 (now updated to 7.7). I haven’t had a ton of time to work on it all at once, so I’ve been adding services one by one as I need them enough to make time for setup.

To get away from having a different login for every different thing I installed Keycloak was one of the first things I set up. Keycloak is an open source identity and access management tool that provides single-sign on with OpenID Connect and SAML. OpenID Connect was easy enough to set up with Jenkins and Gitea (using the appropriate plugins), but when I set up NextCloud I couldn’t find a tutorial (or any documentation really) for the plugin that offered OpenID Connect as an authentication mechanism. This post will document my path to getting a working OpenID Connect login added to my NextCloud instance.

Software Versions

Because I’m only working against a single configuration and don’t know how generally it will apply across other versions, here’s the list of the software I’m using for this post.

Getting Started

I’ll assume from here that all the above pieces are installed and configured for general use, just not hooked up together. From memory: Keycloak needs a realm set up with at least one user that will be set up for Nextcloud and Nextcloud needs the Social Login app installed and enabled on the Apps page.

Keycloak

Go to the Realm Settings page and open the “OpenID Endpoint Configuration” link in a new tab to bring up the .well-known/openid-configuration page. You’ll want the information from this page later to configure the Social Login plugin in Nextcloud.

Open the Clients page and click the create button. Select:

Client IDnextcloud
Client Protocolopenid-connect
Root URLhttps://<URL here>/nextcloud/

Click Save. On the next page (Settings) set:

Access Typeconfidential

Click Save, then click on the Roles tab. Add a new role named “admin”. Click Save, then go to the Mappers tab and add a protocol mapper as follows:

Namerole
Mapper TypeUser Client Role
Client IDnextcloud
Token Claim Namenextcloud-roles
Claim JSON TypeString

Click save, then add the admin role to a Keycloak user as appropriate so admin access is available through the Keycloak authentication. You can verify the mapping and user by going back to clients > nextcloud > Client Scopes > Evaluate, selecting the user, then viewing the Generated Access Token.

Go to the Credentials tab to find the client secret that will be needed in Nextcloud.

Nextcloud

As a Nextcloud administrator user, go to the Settings > Administration > Social login page.

My preferred settings for the first section with reasoning:

  • Disable auto create new users: unchecked to allow users to be created from Keycloak without needing a separate user created in Nextcloud
  • Allow users to connect social logins with their account: unchecked because no users were created on Nextcloud directly.
  • Prevent creating an account if the email address exists in another account: checked
  • Update user profile every login: checked so user changes on Keycloak propagate on next use
  • Do not prune not available user groups on login: unchecked to propagate Keycloak changes on next use
  • Automatically create groups if they do not exists: unchecked to keep Social login from adding groups with the “keycloak-” prefix. I would have this checked if group names didn’t have a prefix added.
  • Restrict login for users without mapped groups: unchecked because all of my Keycloak users currently have access to Nextcloud, even if they don’t have a specific group assigned.
  • Disable notify admins about new users: unchecked

Be sure to click Save: nothing will warn you if you leave the page without saving.

Add a “Custom OpenID Connect” entry (many of these entries will refer to entries in the .well-known/openid-configuration page you opened earlier in Keycloak):

Internal Namekeycloak
Title Keycloak (OIDC)
Authorize url<.well-known entry: authorization_endpoint>
Token url<.well-known entry: token_endpoint>
User info URL <.well-known entry: userinfo_endpoint>
Logout URL <.well-known entry: end_session_endpoint>
Client Idnextcloud
Client Secret<Secret from the Credentials tab in Keycloak>
Scopeopenid
Groups claimnextcloud-roles

If you want to redirect to a specific page (instead of having it load a blank page when it goes to the logout URL) add: ?redirect_uri=<encodedRedirectUri> to the end, where <encodedRedirectUri> is a URI-encoded path to the page to load after logout.

Any roles listed in “nextcloud-roles” will be prefixed by “keycloak-” when they are converted into group names. I suspect, but haven’t confirmed, that it’s from the internal name of the connector. I had to add mappings from each of my roles to the group intended, though in the mapping there isn’t a prefix added, so “admin” -> “admin” correctly assigned users to the admin group. This is why I disabled “Automatically create groups if they do not exist” in the Social login settings.

Again, scroll all the way to the bottom of the page and click Save. Be sure the popup by the banner tells you that the page has saved.

Now go to your Personal > Social login settings page and from the Social login connect > Available providers section click on the Keycloak (OIDC) button. This will either bring you to your keycloak login page or, if you’re already logged in, simply add an entry for keycloak to your user.

Debugging

The easiest way I found to test was to have one tab logged in to the Keycloak administrator pages, one tab logged into my Nextcloud admin account, and a private window that I could log in and out of as needed as I tweaked controls for both parts.

Here a couple of the problems I ran into and why they were showing up:

ProblemResolution
No login button next to
SSO & SAML logins
Social login buttons are added to the
Direct log in page
Error: No id_token was found. Scope was set incorrectly, resulting in the
wrong data being read by Nextcloud.

Conclusion

At this point I have everything functioning so I can either connect social login to my current accounts or create accounts on Keycloak and have them be created in Nextcloud when used to log in, as well as assigning the admin group based on user role from Keycloak.

I may soon configure the login page to automatically redirect to the Keycloak OIDC connector (set ‘social_login_auto_redirect’ => true setting in config.php), but for now I’ll accept an extra click or two to log in, at least until I’ve used it for long enough for all of my sessions to time out and be logged back in.

Sharing Music from Linux

Last weekend I finally got fed up with the movie player that came with Ubuntu for playing music and started looking for alternatives. It turns out Rythmbox is the music player that came with Ubuntu, but it wasn’t set as the default for opening audio files. It was rather easy to import my music directory into it, but about ten seconds into the import the ftp to my file server died and killed the import. I don’t know why it disconnected, but I figured there had to be a decent way to share the music directly from my server over the network instead of connecting with ftp and playing music from the file mount.

I finally got around to looking into that this weekend, and almost immediately found mt-daapd. Rythmbox automatically discovers DAAP servers on the local network on start, so I figured I’d try it. Supposedly, ITunes will discover DAAP servers too, so I’ll even be covered if I boot into Windows for some reason.

Mt-daapd was by far the easiest thing I’ve set up on my server. It installed with apt-get: sudo apt-get install mt-daapd. The installer even set it up to start on boot and started the service. Unfortunately, it didn’t have a clue where to find my music (since I don’t keep my music in my home directory), so I had to edit the conf file: sudo vi /etc/mt-daapd.conf and set the mp3_dir property to the directory all my music is in. At that point I restarted my server (to make sure the start on boot script was working before I forgot about it), opened Rythmbox, and everything just worked.

My only complaint now is that Rythmbox won’t let me search by genre, but it will let me sort by genre, so I can just select the set of songs from the list that I feel like listening to and add those to the play queue.

Misc update

I finally booted my laptop back to Linux, and it’s so much more usable now! I’ve been using Windows Vista since Christmas because I was gaming on my laptop and because I got itunes gift cards and I have itunes installed in windows. The problem I had was that I couldn’t access my file server from windows (it’s a linux server). I figured Samba hadn’t started or something last time I took updates and rebooted the server, so I tried SSHing in from my phone, then realized that I could just use my laptop, so I switched it to Ubuntu. Now Firefox is responsive, I don’t get pop-ups from MS Security Essentials, and the screensaver comes on consistently. In other words: this is a major improvement.

I never did figure out why my server wasn’t showing up on the network list in windows. Before my laptop was finished booting I tried typing in the IP address directly in windows explorer and that worked, but the network browser still won’t find it.

I uploaded the last of the rocket videos:

I ended up trimming off all the extra video of it hanging in the tree. There are a couple spots where you can see my dad and I walking around under it, but it was more long and drawn out than interesting.

The other video I produced this week was in skyrim:

I found a dragon that had a ledge behind it, so I snuck on to the ledge and stabbed it with my daggers for the sneak attack bonus. Unfortunately, I hadn’t improved my offhand dagger with blacksmithing so I didn’t actually one-shot the dragon. I finished it off using my bow when it landed – I haven’t fought many dragons as a melee character but I remember my mage getting bitten and killed when I got close.

It took me probably fifteen minutes to get into position for that attack because every time the dragon detected me it would fly up and breathe frost on me so I’d have to reload a save. Also, to get onto the ledge I had to find a spot to climb the mountain so I could jump down on it. This was the dragon on the mountain south of Riften.

I just realized I didn’t have a category for Games: Skyrim. I guess I really haven’t been blogging much since it came out.

Today I finally sat down and timed a solve of my 7-cube: 30 minuntes 56.77 seconds. That beats my previous time of 63 minutes by far, but I need to do a few more solves for a 3 of 5 average (technically they should all be in one sitting, but at 30 min per solve that’s not happening). I also did a few 3-cube solves and managed a 34.99 second solve, which is my new record for the method I’m using to solve it. I was trying to solve my rubik’s cube while on my exercise bike, but I was both slowing down on the bike and messing up algorithms so I gave up. If I’d had better light maybe it would have been an interesting challenge, perhaps tomorrow.