5

I'm trying to setup SSO with nextcloud (13.0.4) and keycloak (4.0.0.Final) (as SSO/SAML IDP und user management solution) like described at SSO with SAML, Keycloak and Nextcloud.

However, trying to login to nextcloud with the SSO test user configured in keycloak, nextcloud complaints with the following error:

OneLogin_Saml2_ValidationError: Found an Attribute element with duplicated Name

/var/www/html/nextcloud/custom_apps/user_saml/3rdparty/vendor/onelogin/php-saml/lib/Saml2/Auth.php - line 177: OneLogin_Saml2_Response->getAttributes()
/var/www/html/nextcloud/custom_apps/user_saml/lib/Controller/SAMLController.php - line 219: OneLogin_Saml2_Auth->processResponse('ONELOGIN_1111a8...')
[internal function] OCA\User_SAML\Controller\SAMLController->assertionConsumerService()
/var/www/html/nextcloud/lib/private/AppFramework/Http/Dispatcher.php - line 161: call_user_func_array(Array, Array)
/var/www/html/nextcloud/lib/private/AppFramework/Http/Dispatcher.php - line 91: OC\AppFramework\Http\Dispatcher->executeController(Object(OCA\User_SAML\Controller\SAMLController), 'assertionConsum...')
/var/www/html/nextcloud/lib/private/AppFramework/App.php - line 115: OC\AppFramework\Http\Dispatcher->dispatch(Object(OCA\User_SAML\Controller\SAMLController), 'assertionConsum...')
/var/www/html/nextcloud/lib/private/AppFramework/Routing/RouteActionHandler.php - line 47: OC\AppFramework\App main('OCA\\User_SAML\\C...', 'assertionConsum...', Object(OC\AppFramework\DependencyInjection\DIContainer), Array)
[internal function] OC\AppFramework\Routing\RouteActionHandler->__invoke(Array)
/var/www/html/nextcloud/lib/private/Route/Router.php - line 297: call_user_func(Object(OC\AppFramework\Routing\RouteActionHandler), Array)
/var/www/html/nextcloud/lib/base.php - line 999: OC\Route\Router->match('/apps/user_saml...')
/var/www/html/nextcloud/index.php - line 42: OC handleRequest()
{main}
enter

I wonder if there is a way to avoid/filter duplicate attribute names in keycloak to circumvent the problem?

I've set up a test docker-compose.yml to show the problem (localhost only, without https, i.e. for testing only).

# Use only for testing the BASE_PATH feature
# An unencrypted nextcloud will be accessible at
# http://localhost/${BASE_PATH}
version: '3.3'
services:
  app:
    image: aanno/nextcloud:13.0.4-apache
    ports: 
        - 8081:80
    container_name: nextcloud-docker-apache
    volumes:
# Attention: Adapt this to your BASE_PATH
#      - ./apps:/var/www/html/nextcloud/custom_apps
#      - ./config:/var/www/html/nextcloud/config
       - ./data:/var/www/html/nextcloud/data
    environment:
        - BASE_PATH=/nextcloud
    networks:
        - bridge
  keycloak_container:
    image: jboss/keycloak
    container_name: keycloak-server
    ports:
      - 8080:8080
    environment:
      - PROXY_ADDRESS_FORWARDING=true
      # defaults to:
      # -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m
      # -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true
      #- JAVA_OPTS=-Xmx512m
      - DB_VENDOR=h2
      - KEYCLOAK_USER=admin
      - KEYCLOAK_PASSWORD=admin1234
    networks:
        - bridge

networks:
    bridge:
        external:
            name: app

Keycloak will be at http://localhost:8080 and nextcloud at http://localhost:8081/nextcloud . This file could be found also at https://github.com/aanno/nextcloud-docker/blob/tp/set-base-url-2/13.0/apache/test/docker-compose.yml . At this place you also can details about the docker image (it is based on the official nextcloud/docker image for 13.0-apache).

aanno
  • 638
  • 8
  • 17
  • In my example I did **not** setup a identitiy Provider (idp). So I don't what is you configuration in that part. Also, I'd be interested to know **why** you set it up (your keycloak + nextcloud will run just fine without one). Please [edit](https://stackoverflow.com/posts/51011422/edit) your and add more details how you setup keycloak and nextcloud and also why you are trying to use a idp. – MadMike Jun 25 '18 at 07:02
  • Dear MadMike, perhaps my wording was a bit fuzzy first and hence I edited my question a bit. What I actually did is to follow your solution step by step (the only difference I'm aware of is that I use another docker image for nextcloud). However, I always get the mentioned error. – aanno Jun 26 '18 at 19:13
  • What did you use instead of `domain.com`? Did you create more than one user? Did you create a user directly on nextcloud? Which docker-image do you use? Speaking of which... please post your docker-compose.yml... remove the passwords, leave the rest. – MadMike Jun 27 '18 at 10:19
  • I added a docker-compose file to my question to show the problem (on localhost). But I also tried on a real domain (with https by let's encrypt) and run into the very same problem. – aanno Jun 27 '18 at 20:02
  • I wouldn't know where to start looking with this kind of error. I've never had one like this. Maybe ask https://help.nextcloud.com/ ? – MadMike Jun 28 '18 at 13:28
  • Does this apply ? https://help.nextcloud.com/t/solved-nextcloud-saml-keycloak-as-identity-provider-issues/19293/4 – MadMike Jun 28 '18 at 13:30

2 Answers2

6

Because I also posted this as bug at https://github.com/nextcloud/user_saml/issues/222 , I now know the solution: You have to activate the 'Single Role Attribute' switch.

In keycloak 4.0.0.Final the option is a bit hidden under: (Realm) -> Client Scopes -> role_list (saml) -> Mappers tab -> role list -> 'Single Role Attribute'.

aanno
  • 638
  • 8
  • 17
4

There now is a better answer, posted at https://github.com/nextcloud/user_saml/issues/222#issuecomment-648974404

waza-ari commented 23 days ago

I know this one is quite old, but its one of the pages you stumble across when looking for this problem. There is a better option than the proposed one! The proposed option changes the role_list for every Client within the Realm. It is better to override the setting on client level to make sure it only impacts the Nextcloud client.

For this. edit your client, go to Client Scopes and remove role_list from the Assigned Default Client Scopes.

Next, create a new Mapper to actually map the Role List:

Name: anything you like
Mapper Type: Role List
Role Attribute name: Role
Friendly Name: Anything you like
SAML Attribute Name Format: Basic
Single Role Attribute: ON

Hope this helps someone.

aanno
  • 638
  • 8
  • 17