Hi there, I'm testing SOGo with SAML authentication, my ID provider is Keycloak 24.0.1.
I've managed to set up the integration, I'm correctly being redirected to Keycloak upon logging in, and I'm being redirected back to SOGo once logged in, but then SOGo sends me back again to the IDP, and so on in an infinite loop. The following is the sequence of urls: http://localhost:8081/SOGo which redirects to http://localhost:8088/realms/ase/protocol/saml?SAMLRequest=<...>&SigAlg=<...>&Signature=<...> then I see a POST to http://localhost:8081/SOGo/saml2-signon-post which returns a successful SAMLResponse and then a redirect to http://localhost:8081/SOGo//myuser which seems to log out the logged user: I see that this call unsets the cookie 0xHIGHFLYxSOGo actually it is being set to "discard" and its validity is set to yesterday. Can you please point me in the right direction? I see the following in SOGo logs ========================================================================================= sogo | May 03 07:14:25 sogod [88]: |SOGo| starting method 'GET' on uri '/SOGo/myuser' sogo | May 03 07:14:25 sogod [88]: |SOGo| traverse(acquire): SOGo => myuser sogo | May 03 07:14:25 sogod [88]: |SOGo| do traverse name: 'SOGo' sogo | May 03 07:14:25 sogod [88]: |SOGo| do traverse name: 'myuser' sogo | May 03 07:14:25 sogod [88]: |SOGo| traverse miss: name=myuser, acquire: i=1,count=2 sogo | May 03 07:14:25 sogod [88]: |SOGo| miss is last object. sogo | May 03 07:14:25 sogod [88]: |SOGo| handle miss error: <SoAuthRequiredException: 0x5abe8b185410> NAME:SoAuthRequired REASON:authentication required ========================================================================================= I'm attaching my configuration (Dockerfile, sogo.conf and Apache site.conf) : I use SOGo with keycloak, postgresql and memcached in docker compose =================================== Dockerfile ===================================================== FROM ubuntu:20.04 # Update all packages and install the apt tools to install the rest RUN apt update && \ apt upgrade -y && \ apt install -y gnupg2 apt-utils ca-certificates apt-transport-https wget # Add the PGP Key of SOGo RUN wget -O- "https://keys.openpgp.org/vks/v1/by-fingerprint/74FFC6D72B925A34B5D356BDF8A27B36A6E2EAE9" | gpg --dearmor | apt-key add - # Download SOGO from this repo: COPY SOGo.list /etc/apt/sources.list.d/SOGo.list # Update apt cache and install SOGo RUN apt update && \ # Switch to non-interactive install export DEBIAN_FRONTEND=noninteractive && \ # Do the time zone settings beforehand so we don't get promted for it during install (pick your timezone) echo "tzdata tzdata/Areas select Europe" | debconf-set-selections && \ echo "tzdata tzdata/Zones/Europe select Berlin" | debconf-set-selections && \ echo "tzdata tzdata/Zones/Etc select UTC" | debconf-set-selections && \ # For some reason SOGo wants this file to be present mkdir -p /usr/share/doc/sogo/ && touch /usr/share/doc/sogo/foo.sh && \ # Install the actual services needed apt install -y --no-install-recommends apache2 sope4.9-gdl1-postgresql sogo supervisor gosu && \ # Prepare non-privileged file permissions for SOGo chown sogo /etc/sogo/sogo.conf && \ mkdir -p /var/run/sogo && chown sogo /var/run/sogo && \ # Apache also runs on a non-privileged user mkdir -p /var/run/apache2 && chown www-data /var/run/apache2 && \ # Activate the necessary Apache mods and disable the default site a2enmod proxy headers proxy_http rewrite && \ a2dissite 000-default && \ # Verify that gosu works gosu nobody true # This file is explained below COPY config/supervisord.conf /etc/supervisord/supervisord.conf COPY config/sogo.conf /etc/sogo/sogo.conf COPY config/idp-metadata.xml /etc/sogo/idp-metadata.xml COPY config/saml.key /etc/pki/tls/private/saml.key COPY config/saml.pem /etc/pki/tls/certs/saml.pem COPY config/idp.pub /etc/pki/tls/certs/idp.pub COPY config/idp.pem /etc/pki/tls/certs/idp.pem RUN chmod 644 /etc/pki/tls/private/saml.key /etc/pki/tls/certs/saml.pem COPY config/site.conf /etc/apache2/sites-enabled/sogo.conf # Supervisord will start Apache and SOGo CMD exec /usr/bin/supervisord -c /etc/supervisord/supervisord.conf ============================================================================================================================== =========================================== sogo.conf =========================================================================== { /* ********************* Main SOGo configuration file ********************** * * * Since the content of this file is a dictionary in OpenStep plist format, * * the curly braces enclosing the body of the configuration are mandatory. * * See the Installation Guide for details on the format. * * * * C and C++ style comments are supported. * * * * This example configuration contains only a subset of all available * * configuration parameters. Please see the installation guide more details. * * * * ~sogo/GNUstep/Defaults/.GNUstepDefaults has precedence over this file, * * make sure to move it away to avoid unwanted parameter overrides. * * * * **************************************************************************/ /* Database configuration (mysql:// or postgresql://) */ SOGoProfileURL = "postgresql://sogo:sogo@ase-db:5432/sogo/sogo_user_profile"; OCSFolderInfoURL = "postgresql://sogo:sogo@ase-db:5432/sogo/sogo_folder_info"; OCSSessionsFolderURL = "postgresql://sogo:sogo@ase-db:5432/sogo/sogo_sessions_folder"; /* Mail */ //SOGoDraftsFolderName = Drafts; //SOGoSentFolderName = Sent; //SOGoTrashFolderName = Trash; SOGoIMAPServer = "imaps://imap.example.tld:143/?tls=yes"; SOGoSieveServer = sieve://sieve.example.tld:4190; SOGoSMTPServer = smtp.example.tld; SOGoMailDomain = example.tld; SOGoMailingMechanism = smtp; SOGoForceExternalLoginWithEmail = YES; SOGoSMTPAuthenticationType = PLAIN; SOGoForceExternalLoginWithEmail = YES; //SOGoMailSpoolPath = /var/spool/sogo; //NGImap4ConnectionStringSeparator = "/"; /* Notifications */ //SOGoAppointmentSendEMailNotifications = NO; //SOGoACLsSendEMailNotifications = NO; //SOGoFoldersSendEMailNotifications = NO; /* Authentication */ SOGoPasswordChangeEnabled = NO; /* SAML configuration */ SOGoAuthenticationType = saml2; SOGoSAML2PrivateKeyLocation = "/etc/pki/tls/private/saml.key"; SOGoSAML2CertificateLocation = "/etc/pki/tls/certs/saml.pem"; SOGoSAML2IdpMetadataLocation = "/etc/sogo/idp-metadata.xml"; // this comes from http://localhost:8088/realms/ase/protocol/saml/descriptor SOGoSAML2IdpPublicKeyLocation = "/etc/pki/tls/certs/idp.pub"; SOGoSAML2IdpCertificateLocation = "/etc/pki/tls/certs/idp.pem"; SOGoSAML2LoginAttribute = "username"; //SOGoSAML2LogoutEnabled = YES; //SOGoSAML2LogoutURL = "http://localhost/SOGo"; /* LDAP authentication example */ //SOGoUserSources = ( // { // type = ldap; // CNFieldName = cn; // UIDFieldName = uid; // IDFieldName = uid; // first field of the DN for direct binds // bindFields = (uid, mail); // array of fields to use for indirect binds // baseDN = "ou=users,dc=acme,dc=com"; // bindDN = "uid=sogo,ou=users,dc=acme,dc=com"; // bindPassword = qwerty; // canAuthenticate = YES; // displayName = "Shared Addresses"; // hostname = ldap://127.0.0.1:389; // id = public; // isAddressBook = YES; // } //); /* LDAP AD/Samba4 example */ //SOGoUserSources = ( // { // type = ldap; // CNFieldName = cn; // UIDFieldName = sAMAccountName; // baseDN = "CN=users,dc=domain,dc=tld"; // bindDN = "CN=sogo,CN=users,DC=domain,DC=tld"; // bindFields = (sAMAccountName, mail); // bindPassword = password; // canAuthenticate = YES; // displayName = "Public"; // hostname = ldap://127.0.0.1:389; // filter = "mail = '*'"; // id = directory; // isAddressBook = YES; // } //); /* SQL authentication example */ /* These database columns MUST be present in the view/table: * c_uid - will be used for authentication - it's the username or usern...@domain.tld) * c_name - which can be identical to c_uid - will be used to uniquely identify entries * c_password - password of the user, plain-text, md5 or sha encoded for now * c_cn - the user's common name - such as "John Doe" * mail - the user's mail address * See the installation guide for more details */ //SOGoUserSources = // ( // { // type = sql; // id = directory; // viewURL = "postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_view"; // canAuthenticate = YES; // isAddressBook = YES; // userPasswordAlgorithm = md5; // } // ); /* Web Interface */ //SOGoPageTitle = SOGo; //SOGoVacationEnabled = YES; //SOGoForwardEnabled = YES; //SOGoSieveScriptsEnabled = YES; //SOGoMailAuxiliaryUserAccountsEnabled = YES; //SOGoTrustProxyAuthentication = NO; //SOGoXSRFValidationEnabled = YES; /* General */ //SOGoLanguage = English; //SOGoTimeZone = America/Montreal; //SOGoCalendarDefaultRoles = ( // PublicDAndTViewer, // ConfidentialDAndTViewer //); //SOGoSuperUsernames = (sogo1, sogo2); // This is an array - keep the parens! //SxVMemLimit = 384; //WOPidFile = "/var/run/sogo/sogo.pid"; // reach memcached through docker SOGoMemcachedHost = "ase-memcached"; // this has a great impact on performance: you should adjust the number // of workers according to the number of users and the performance of your // machine WorkersCount = 4; /* Debug */ SoDebugObjectTraversal = YES; SOGoDebugRequests = YES; SoDebugBaseURL = YES; //ImapDebugEnabled = YES; //LDAPDebugEnabled = YES; PGDebugEnabled = YES; //MySQL4DebugEnabled = YES; SOGoUIxDebugEnabled = YES; WODontZipResponse = YES; WOLogFile = /var/log/sogo/sogo.log; WOWorkersCount = 10; } ============================================================================================================================== ======================================================== Apache site.conf ======================================================== <VirtualHost *:80> Alias /SOGo.woa/WebServerResources/ \ /usr/lib/GNUstep/SOGo/WebServerResources/ Alias /SOGo/WebServerResources/ \ /usr/lib/GNUstep/SOGo/WebServerResources/ <Directory /usr/lib/GNUstep/SOGo/> AllowOverride None <IfVersion < 2.4> Order deny,allow Allow from all </IfVersion> <IfVersion >= 2.4> Require all granted </IfVersion> # Explicitly allow caching of static content to avoid browser specific behavior. # A resource's URL MUST change in order to have the client load the new version. <IfModule expires_module> ExpiresActive On ExpiresDefault "access plus 1 year" </IfModule> </Directory> ## Uncomment the following to enable proxy-side authentication, you will then ## need to set the "SOGoTrustProxyAuthentication" SOGo user default to YES and ## adjust the "x-webobjects-remote-user" proxy header in the "Proxy" section ## below. # ## For full proxy-side authentication: #<Location /SOGo> # AuthType XXX # Require valid-user # SetEnv proxy-nokeepalive 1 # Allow from all #</Location> # ## For proxy-side authentication only for CardDAV and GroupDAV from external ## clients: #<Location /SOGo/dav> # AuthType XXX # Require valid-user # SetEnv proxy-nokeepalive 1 # Allow from all #</Location> ProxyRequests Off SetEnv proxy-nokeepalive 1 ProxyPreserveHost On # When using CAS, you should uncomment this and install cas-proxy- validate.py # in /usr/lib/cgi-bin to reduce server overloading # # ProxyPass /SOGo/casProxy http://localhost/cgi-bin/cas-proxy-validate.py # <Proxy http://localhost/app/cas-proxy-validate.py> # Order deny,allow # Allow from your-cas-host-addr # </Proxy> ProxyPass /SOGo http://127.0.0.1:20000/SOGo retry=0 # Enable to use Microsoft ActiveSync support # Note that you MUST have many sogod workers to use ActiveSync. # See the SOGo Installation and Configuration guide for more details. # #ProxyPass /Microsoft-Server-ActiveSync \ # http://127.0.0.1:20000/SOGo/Microsoft-Server-ActiveSync \ # retry=60 connectiontimeout=5 timeout=360 <Proxy http://127.0.0.1:20000/SOGo> ## adjust the following to your configuration RequestHeader set "x-webobjects-server-port" "8081" RequestHeader set "x-webobjects-server-name" "localhost" RequestHeader set "x-webobjects-server-url" "http://localhost:8081" ## When using proxy-side autentication, you need to uncomment and ## adjust the following line: RequestHeader unset "x-webobjects-remote-user" # RequestHeader set "x-webobjects-remote-user" "%{REMOTE_USER}e" env=REMOTE_USER RequestHeader set "x-webobjects-server-protocol" "HTTP/1.0" AddDefaultCharset UTF-8 Order allow,deny Allow from all </Proxy> # For Apple autoconfiguration <IfModule rewrite_module> RewriteEngine On RewriteRule ^/.well-known/caldav/?$ /SOGo/dav [R=301] RewriteRule ^/.well-known/carddav/?$ /SOGo/dav [R=301] </IfModule> </VirtualHost> ==============================================================================================================================