Categories
Browser Debian IdP Keycloak LDAP Linux Nextcloud SAML Shibboleth SingleSignOn SSO Ubuntu

Nextcloud SAML and LDAP authentication

I’ve been running my nextcloud instance for quite some years now, and I finally decided to change its authentication from LDAP to SAML for a better single sign on experience.

By using keycloak as IdP there’ll also be an option to enable multi factor authentication (MFA) for all connected applications at once.

Where I come from

As I mentioned I’ve been authenticating my nextcloud instance against my (Samba based) LDAP directory service.

Maybe I’ll find some time to describe that in detail later on, but for now let’s assume that a working LDAP based nextcloud is up and running.

What needs to be done?

First of all we’ll need a nextcloud app that can handle SAML authentication. And (not very surprising) there’s one ready to be deployed in the app store called user_saml.

What settings do we need…

… for keycloak (IdP)?

Client settings
Client IDhttps://cloud.mydomain.de
Valid redirect URLshttps://cloud.mydomain.de/index.php/apps/user_saml/saml/acs
Sign documentsOn
Sign assertionsOn

… for nextcloud (user_saml, SP)?

Go to "Administrative Settings" and select "SSO & SAML Authentication".

General
Attribute to map the UID touid
Service Provider Data
Name ID formatTransient
X.509 certificate of the Service ProviderCan be exported/extracted from keycloak (s. below)
Private key of the Service ProviderCan be exported/extracted from keycloak (s. below)
Service Provider EntityId (optional)https://cloud.mydomain.de
Identity Provider Data
Identifier of the IdP entityhttps://keycloak.mydomain.de/realms/MYDOMAIN
Identifier of the IdP entityhttps://keycloak.mydomain.de/realms/MYDOMAIN/protocol/saml
Security settings
Signatures and encryption offeredSelect all
Signatures and encryption requiredSelect the first two

Even more information

This is a basic application configuration:

linux # sudo -u www-data php occ config:list user_saml
{
    "apps": {
        "user_saml": {
            "installed_version": "6.6.0",
            "types": "authentication",
            "enabled": "yes",
            "type": "saml",
            "general-require_provisioned_account": "1",
            "general-allow_multiple_user_back_ends": "1"
        }
    }
}

So in my case I want to re-use the existing LDAP accounts and just change the authentication. So for now we’ll keep both LDAP and SAML authentication enabled (allow_multiple_user_back_ends": "1") and we’ll not auto-create new users, instead they need to be provided by another source (LDAP in my case, require_provisioned_account": "1").

Detailed user_saml app configuration:

linux # sudo -u www-data php occ saml:config:get
  - 1:
    - general-idp0_display_name: SSO Login (Keycloak)
    - general-uid_mapping: uid
    - sp-entityId: https://cloud.mydomain.de
    - idp-entityId: https://keycloak.mydomain.de/realms/MYDOMAIN
    - idp-singleSignOnService.url: https://keycloak.mydomain.de/realms/MYDOMAIN/protocol/saml
    - sp-x509cert: -----BEGIN CERTIFICATE-----
MIICwTCCAakCBgGXhw/ZmzANBgkqhkiG9w0BAQsFADAkMSIwIAYDVQQDDBlodHRw
<...>
zbk2xa10eF0Iv5P65AWl6FNU7KAkwUxlffLqneXdvZc0o3bXKw==
-----END CERTIFICATE-----
    - sp-privateKey: -----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDAyowcmut/n1FS
<...>
ZEEg1UCBooxPcH6uH0amPvhsuUO2IDg7djoaU0P/elOwN5Tr6Av3tcj0hkpXYZYK
NnSt+vDb7e63a5eM2Sn4lQ==
-----END PRIVATE KEY-----
    - idp-x509cert: -----BEGIN CERTIFICATE-----
MIICnzCCAYcCBgF/H7/K6zANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhMSU5V
<...>
P8dQpwufWY7z/Wlp57YB46QHFYjyK7OIJaf1jPyoaaNpqm3PpSJnXSaIeaWDmLYO
/LYe
-----END CERTIFICATE-----
    - security-wantMessagesSigned: 1
    - security-wantAssertionsSigned: 1
    - security-wantAssertionsEncrypted: 0
    - security-wantNameIdEncrypted: 0
    - security-nameIdEncrypted: 1
    - security-authnRequestsSigned: 1
    - security-logoutRequestSigned: 1
    - security-logoutResponseSigned: 1
    - security-signMetadata: 1
    - security-wantNameId: 0
    - security-wantXMLValidation: 1
    - sp-name-id-format: urn:oasis:names:tc:SAML:2.0:nameid-format:transient
    - saml-attribute-mapping-displayName_mapping: displayname
    - saml-attribute-mapping-email_mapping: email

Make sure to get the right certificates/keys from keycloak:

Getting certificates and keys

The idp-x509cert can be retrieved from your IdP’s metadata (URL):

linux # curl -s https://keycloak.mydomain.de/realms/MYDOMAIN/protocol/saml/descriptor | xmllint -format - > /tmp/out.xml
<...>
linux # xmllint --xpath "/*[local-name()='EntityDescriptor' and namespace-uri()='urn:oasis:names:tc:SAML:2.0:metadata']/*[local-name()='IDPSSODescriptor' and namespace-uri()='urn:oasis:names:tc:SAML:2.0:metadata']/*[local-name()='KeyDescriptor' and namespace-uri()='urn:oasis:names:tc:SAML:2.0:metadata']/*[local-name()='KeyInfo' and namespace-uri()='http://www.w3.org/2000/09/xmldsig#']/*[local-name()='X509Data' and namespace-uri()='http://www.w3.org/2000/09/xmldsig#']/*[local-name()='X509Certificate' and namespace-uri()='http://www.w3.org/2000/09/xmldsig#']/text()" /tmp/out.xml > /tmp/idp.pem
<...>

This will however only deliver the content of the certificate, make sure to add the header and footer to this file:

-----BEGIN CERTIFICATE-----
<... content should be here ...>
-----END CERTIFICATE-----

Verify the certificate with:

linux # openssl x509 -in /tmp/idp.pem

This will also add the typical line breaks upon output. If you want to see (only) the plain-text output, add options -noout and -text:

linux # openssl x509 -in /tmp/idp.pem -noout -text

The sp-x509cert and the sp-privateKey will both be created by keycloak while creating a new client.

They can be exported by selecting the nextcloud client from "Clients". Then select the tab "Keys", go to "Certificate" and "Export" this key in "Archive format" "PKCS12" (you’ll be forced to protect the exported cert/key with a password!).

The export will then be downloaded as a file called keystore.p12. You can export cert and key in unencrypted PEM format like this:

linux # openssl pkcs12 -legacy -in keystore.p12 -out sp.key -nocerts -nodes
Enter Import Password:

linux # openssl pkcs12 -legacy -in keystore.p12 -out sp.pem -clcerts -nokeys
Enter Import Password:

Leave a Reply

Your email address will not be published. Required fields are marked *