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>
==============================================================================================================================

Reply via email to