25

I am trying to setup Keycloak as a IdP (Identity Provider) and Nextcloud as a service. I want to setup Keycloak as to present a SSO (single-sign-on) page.

I am running a Linux-Server with a Intel compatible CPU. What is the correct configuration?

  • Keycloak will be running as https://kc.example.com
  • Nextcloud will be running as https://nc.example.com
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
MadMike
  • 1,391
  • 1
  • 16
  • 38

2 Answers2

58

Prerequisite:

To use this answer you will need to replace example.com with an actual domain you own. Also, replace email@example.com with your working e-mail address.

It is assumed you have docker and docker-compose installed and running.

Setup your services with Docker

In addition to keycloak and nextcloud I use:

  • nginx as a reverse-proxy
  • letsencyrpt to generate the SSL-certificates for the sub-domains.

I'm setting up all the needed services with docker and docker-compose. This is how the docker-compose.yml looks like this:

version: '2'

  nginx-proxy:
    image: jwilder/nginx-proxy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/etc/nginx/vhost.d"
      - "./proxy-default.conf:/etc/nginx/conf.d/my-proxy.default.conf:ro"
      - "/usr/share/nginx/html"
      - "/var/run/docker.sock:/tmp/docker.sock:ro"
      - "./le-cert:/etc/nginx/certs:ro"
    labels:
      com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"

  letsencrypt-nginx-proxy-companion:
    image: jrcs/letsencrypt-nginx-proxy-companion
    restart: unless-stopped
    depends_on:
      - nginx-proxy
    container_name: le-proxy-companion
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./le-cert:/etc/nginx/certs:rw"
    volumes_from:
      - nginx-proxy

  keycloak:
    image: jboss/keycloak
    links:
      - keycloak-postgres:postgres
    ports:
      - 8080:8080
    volumes:
      - ./keycloak:/opt/jboss/keycloak
    environment:
      - KEYCLOAK_USER=admin
      - KEYCLOAK_PASSWORD=admin
      - "PROXY_ADDRESS_FORWARDING=true"
      - VIRTUAL_PORT=8080
      - VIRTUAL_HOST=kc.example.com
      - LETSENCRYPT_HOST=kc.example.com
      - LETSENCRYPT_EMAIL=email@example.com

  keycloak-postgres:
    image: postgres
    environment:
      - POSTGRES_DB=keycloak
      - POSTGRES_USER=keycloak
      - POSTGRES_PASSWORD=keycloak

  nextcloud:
    image: hoellen/nextcloud
    environment:
      - UPLOAD_MAX_SIZE=10G
      - APC_SHM_SIZE=128M
      - OPCACHE_MEM_SIZE=128
      - CRON_PERIOD=15m
      - TZ=Europe/Berlin
      - DOMAIN=nc.example.com
      - ADMIN_USER=admin
      - ADMIN_PASSWORD=admin
      - DB_TYPE=mysql
      - DB_NAME=nextcloud
      - DB_USER=nextcloud
      - DB_PASSWORD=nextcloud
      - DB_HOST=nc-db
    volumes:
      - ./nc/nc-data:/data
      - ./nc/nc-config:/config
      - ./nc/nc-apps:/apps2
      - ./nc/nc-themes:/nextcloud/themes
    environment:
      - VIRTUAL_HOST=nc.example.com
      - LETSENCRYPT_HOST=nc.example.com
      - LETSENCRYPT_EMAIL=email@example.com

  nc-db:
    image: mariadb
    volumes:
      - ./nc/nc-db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=nextcloud
      - MYSQL_PASSWORD=nextcloud
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

I put my docker-files in a folder docker and within this folder a project-specific folder. Here keycloak. Create them with:

mkdir -p ~/docker/keycloak

Create the docker-compose.yml-File with your preferred editor in this folder. Start the services with:

cd ~/docker/keycloak
docker-compose up -d

Wait a moment to let the services download and start. Check if everything is running with:

docker-compose ps

If a service isn't running. Issue a second docker-compose up -d and check again.

Configure Keycloak, add a new Realm

Open a browser and go to https://kc.example.com. Click on Administration Console. As specified in your docker-compose.yml, Username and Password is admin.

On the top-left of the page, you need to create a new Realm. Click Add. Enter my-realm as the name. Click Save.

Click on the Keys-tab. Look at the RSA-entry. We will need to copy the Certificate of that line. Click on Certificate and copy-paste the content to a text editor for later use.

Prepare a Private Key and Certificate for Nextcloud

Open a terminal and issue:

openssl req  -nodes -new -x509  -keyout private.key -out public.cert

This creates two files: private.key and public.cert which we will need later for the nextcloud service.

Configure Nextcloud

Open a browser and go to https://nc.example.com. As specified in your docker-compose.yml, Username and Password is admin.

You need to activate the SSO & Saml Authenticate which is disabled by default.

Important From here on don't close your current browser window until the setup is tested and running. If you close the browser before everything works you probably not be able to change your settings in nextcloud anymore. In such a case you will need to stop the nextcloud- and nextcloud-db-container, delete their respective folders, recreate them and start all over again.

Click on the top-right gear-symbol and then on the + Apps-sign. On the left now see a Menu-bar with the entry Security. Click it. You now see all security-related apps. Click on the Activate button below the SSO & SAML authentication App.

Click on the top-right gear-symbol again and click on Admin. Click on SSO & SAML authentication.

Use the following values:

  • Attribute to map UID to: username
  • Enable "Use SAML auth for the Nextcloud desktop clients (requires user re-authentication)"
  • Copy the content of public.cert into the 'X.509 Certificate'-field
  • Copy the content of private.key into the 'Private key of Service Provider'-field.
  • Identifier of the IdP: https://kc.example.com/realms/my-realm
  • URL Target of the IdP where the SP will send the Authentication Request Message: https://kc.example.com/realms/my-realm/protocol/saml
  • URL Location of IdP where the SP will send the SLO Request: https://kc.example.com/realms/my-realm/protocol/saml
  • Public X.509 certificate of the IdP: Copy the certificate from Keycloak from the Keys-tab of my-realm. You will need to add '-----BEGIN CERTIFICATE-----' in front of the key and '-----END CERTIFICATE-----' to the end of it.
  • In-Service Provider Data:
    • Attribute, displayname: username
    • Attribute, email address: email
  • Security Settings, enable the following options:
    • Indicates whether the <samlp:AuthnRequest> messages sent by this SP will be signed. [Metadata of the SP will offer this info]
    • Indicates whether the <samlp:logoutRequest> messages sent by this SP will be signed.
    • Indicates whether the <samlp:logoutResponse> messages sent by this SP will be signed.
    • Indicates a requirement for the <samlp:Response>, <samlp:LogoutRequest> and <samlp:LogoutResponse> elements received by this SP to be signed.
    • Indicates a requirement for the <saml:Assertion> elements received by this SP to be signed. [Metadata of the SP will offer this info]
  • Check there is a Metadata valid beside the Download metadata XML-Button This part of the configuration should look like this
  • Click the Download metadata XML-Button. This generates and sends an XML file. Save it for use in the next step.

Configure Keycloak, Client

Access the Administrator Console again. Click on Clients and on the top-right click on the Create-Button.

Next to Import, click the Select File-Button. Select the XML-File you've created on the last step in Nextcloud.

and click Save.

You are presented with a new screen. Change the following fields:

  • Name: Nextcloud
  • Valid Redirect URIs: https://nc.example.com/ *
  • Click Save

On the Tab Mappers:

  • Click Delete-Button on the preassigned role list (if it exists)
  • Click Create
    • Name: username
    • Mapper Type: User Property
    • Property: username
    • SAML Attribute Name: username
    • SAML Attribute NameFormat: Basic
    • Click Save
  • Click Create
    • Name: email
    • Mapper Type: User Property
    • Property: email
    • SAML Attribute Name: email
    • SAML Attribute NameFormat: Basic
    • Click Save
  • Click Create
    • Name: Roles
    • Mapper Type: Role List
    • Role attribute name: Roles
    • Friendly Name: roles
    • SAML Attribute NameFormat: Basic
    • Single Role Attrubute: On
    • Click Save

Configure Keycloak, Add user

  • On the left side, click on Users
  • On the top-right, click Add users
  • Set the following values:
    • Username: user
    • Email: user@example.com
    • Click Save
  • On the tab Credentials:
    • New Password: user
    • Password Confirmation: user
    • Temporary: Off
    • Click Reset Password
  • A Window pops up:
    • Click Change Password

Test run

Open a new browser window in incognito/private mode. Eg. for google-chrome press Ctrl-Shift-N, in Firefox press Ctrl-Shift-P. Keep the other browser window with the nextcloud setup page open. Else you might lock yourself out.

Access https://nc.example.com with the incognito/private browser window. You are presented with the keycloak username/password page. Enter user as a name and password. You should be greeted with the nextcloud welcome screen.

Acknowledgement

Philip
  • 23,316
  • 2
  • 31
  • 31
MadMike
  • 1,391
  • 1
  • 16
  • 38
  • MadMike, I tried to use your recipe, but I encounter a 'OneLogin_Saml2_ValidationError: Found an Attribute element with duplicated Name' error in nextclould with nextcloud 13.0.4 and keycloak 4.0.0.Final. See my [question](https://stackoverflow.com/questions/51011422/is-there-a-way-to-filter-avoid-duplicate-attribute-names-in-keycloak-saml-assert) for details. – aanno Jun 24 '18 at 15:53
  • 1
    Thank your for this nice tutorial. There's one thing to mention, though: If you tick`"Enable "Use SAML auth for the Nextcloud desktop clients (requires user re-authentication)`, then the Nextcloud desktop client didn't work for me (stuck on "redirect" screen). Using the ownCloud client solved this, but left us with another problem: Users have to re-authenticate everytime they quit the client, which is really annoying. Happens both on Windows and Ubuntu 18.04. **What solves this is simply not ticking it.** – bellackn Nov 29 '18 at 11:38
  • @bellackn Unfortunatly I've stopped using Keycloak with SAML and moved to use OIDC instead. My test-setup for SAML is gone so I can just nod silently toward any suggested improvements... thanks anyway for sharing your insights for future visitors :) – MadMike Nov 30 '18 at 07:23
  • 1
    @MadMike how did you connect Nextcloud with OIDC? – srnjak Feb 15 '19 at 23:30
  • 1
    @srnjak I didn't... yet. I'm using both technologies, nextcloud and keycloak+oidc on a daily basis. It's just that I use nextcloud privatly and keycloak+oidc at work. I've used both nextcloud+keycloak+saml here to have a complete working example. At that time I had more time at work to concentrate on sso matters. Unfortunatly this has changed since. It's still a priority... along with some new priorites :-| If I might suggest: Open a new question and list your requirements. I'm sure I'm not the only one with ideas and expertise on the matter. I promise to have a look at it. – MadMike Feb 16 '19 at 06:18
  • I'd like to add another thing that mislead me: The "Public X.509 certificate of the IdP" point is what comes up when you click on "Certificate", and _not_ "Public key". – bellackn Apr 23 '19 at 12:50
  • 1
    Keycloak 4 and nextcloud 17 beta: I had no preasigned "role list", I had to click "add builtin" to add the "role list". Then edit it and toggle "single role attribute" to TRUE. I guess by default that role mapping is added anyway but not displayed. – Neikius Aug 22 '19 at 21:02
  • Did people managed to make SLO work? I always get a Internal server error with the configuration above. – Pierre Ozoux Jan 06 '20 at 15:20
  • As I switched now to OAUTH instead of SAML I can't easily re-test that configuration. Anyway: If you want the stackoverflow-community to have a look into your case you **need** to ask a new question a give us all the details. – MadMike Jan 06 '20 at 15:32
  • 1
    Not a specialist, but the openssl cli you specify creates a certificate that expires after 1 month. I added "-days 3650" to make it valid 10 years `openssl req -nodes -new -x509 -days 3650 -keyout private.key -out public.cert` – Chris Browet Mar 25 '20 at 14:35
  • for me this tut worked like a charm. Had a few problems with the clientId, because I was confused that is an url, but after that it worked. – HasBert Sep 12 '20 at 21:21
  • 1
    FYI, Keycloak+Nextcloud+OIDC works with nextcloud apps [Social Login](https://github.com/zorn-v/nextcloud-social-login) and [OpenID Connect Login](https://github.com/pulsejet/nextcloud-oidc-login). There is apparently a Nextcloud-native (in-house) [user_oidc](https://github.com/nextcloud/user_oidc) in the works, but it is under-documented and has not seen recent activity. – r2evans Jan 09 '21 at 22:16
  • Was getting"saml user not provisioned" issue, finally got it working after making a few changes: 1) I had to disable "Only allow authentication if an account exists on some other backend. (e.g. LDAP)" in nextcloud. 2)to get the X.509 of IdP, open keycloak -> realm settings -> click on SAML 2.0 Identity Provider Metadata right at the bottom. This will open an xml with the correct x.509. 3) open clients -> (newly created client) ->Client Scopes-> Assigned Default Client Scopes - select the rules list and remove it. This finally got it working for me. – jitin Mar 25 '22 at 15:02
  • Have you got the situation, that SAML with Nextcloud and Keycloak only works on Firefox? But on Chrome I just get redirected to the login screen again. This is totally weird. – Mohammed Noureldin Mar 27 '23 at 23:46
4

Here is a slightly updated version for nextcloud 15/16:

Open a browser and go to https://kc.example.com. Click on Administration Console. As specified in your docker-compose.yml, Username and Password is admin.

On the top-left of the page you need to create a new Realm. Click Add. Enter my-realm as name. Click Save.

Click on the Keys-tab. Look at the RSA-entry. We will need to copy the Certificate of that line. Click on Certificate and copy-paste the content to a text editor for later use. Prepare a Private Key and Certificate for Nextcloud

Open a terminal and issue:

OpenSSL req -nodes -new -x509 -keyout private.key -out public.cert

This creates two files: private.key and public.cert which we will need later for the nextcloud service. Configure Nextcloud

Open a browser and go to https://nc.example.com. As specified in your docker-compose.yml, Username and Password is admin.

You need to activate the SSO & Saml Authenticate which is disabled by default.

Important From here on don't close your current browser window until the setup is tested and running. If you close the browser before everything works you probably not be able to change your settings in nextcloud anymore. In such a case you will need to stop the nextcloud- and nextcloud-db-container, delete their respective folders, recreate them and start all over again.

Click on top-right gear-symbol and the then on the + Apps-sign. On the left now see a Menu-bar with the entry Security. Click it. You now see all security realted apps. Click on the Activate button below the SSO & SAML authentication App.

Click on top-right gear-symbol again and click on Admin. Click on SSO & SAML authentication.

Use the following values:

Attribute to map UID to:username
Enable "Use SAML auth for the Nextcloud desktop clients (requires user re-authentication)"
Copy the content ofpublic.cert into the 'X.509 Certificate'-field
Copy the content ofprivate.key into the 'Private key of Service Provider'-field.
Identifier of the IdP: https://kc.example.com/auth/realms/my-realm
URL Target of the IdP where the SP will send the Authentication Request Message: https://kc.example.com/auth/realms/my-realm/protocol/saml
URL Location of IdP where the SP will send the SLO Request: https://kc.example.com/auth/realms/my-realm/protocol/saml
Public X.509 certificate of the IdP: Copy the certificate from Keycloak from the Keys-tab of my-realm. You will need to add '-----BEGIN CERTIFICATE-----' in front of the key and '-----END CERTIFICATE-----' to the end of it.
In Identity Provider Data:
    Attribute, displayname: username
    Attribute, email adress: email
    Attribute, Quota: nextcloudquota
    Click Download metadata XML and save the file for the next step.
Security Settings, enable the following options:
    Indicates whether the messages sent by this SP will be signed. [Metadata of the SP will offer this info]
    Indicates whether the messages sent by this SP will be signed.
    Indicates whether the messages sent by this SP will be signed.
    Indicates a requirement for the , and elements received by this SP to be signed.
    Indicates a requirement for the elements received by this SP to be signed. [Metadata of the SP will offer this info]
Check there is a Metadata valid beside the Download metadata XML-Button
Click the Download metadata XML-Button. This generate and send a XML file. Save it.

Configure Keycloak, Client

Access the Administror Console again. Click on Clients and on the top-right click on the Create-Button.

Next to Import, Click the Select File-Button. Select the XML-File you've create on the last step in Nextcloud.

Change:

Client SAML Endpoint: https://kc.example.com/auth/realms/my-realm

and click Save.

You are presented with a new screen. Change the following fields:

Name: Nextcloud
Valid Redirect URIs: https://nc.example.com/ *
Click Save

On the Tab Matters:

Click Delete-Button on the preassigned role list
Click Create
    Name: username
    Mapper Type: User Property
    Property: username
    SAML Attribute Name: username
    SAML Attribute NameFormat: Basic
    Click Save
Click Create
    Name: email
    Mapper Type: User Property
    Property: email
    SAML Attribute Name: email
    SAML Attribute NameFormat: Basic
    Click Save

Click Create

Name: Roles
Mapper Type: Role List
Role attribute name: Roles
Friendly Name: roles
SAML Attribute NameFormat: Basic
Single Role Attrubute: On
Click Save

Click Create

Name: nextcloudquota
Mapper Type: User Property
Property: nextcloudquota
SAML Attribute Name: nextcloudquota
SAML Attribute NameFormat: Basic
Click Save

Configure Keycloak, Add user

On the left side, click on Users
On the top-right, click Add users
Set the following values:
    Username: user
    Email: user@example.com
    Click Save
On the tab Credentials:
    New Password: user
    Password Confirmation: user
    Temporary: Off
    Click Reset Password
A Window pops up:
    Click Change Password
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109