Hi,
after trying to the SAML working with dovecot without success for
several days I tried a different approach today. Instead off using
SAML I switched to use the libapache2-mod-auth-openidc module. I
changed the apache sogo.conf to support the OIDC module with the
settings below. Please note that you need to add some checks about
valid claims, take a look at
https://github.com/OpenIDC/mod_auth_openidc/wiki -> "Require claim
sub:<userid>".
--- /etc/apache2/sites-available/sogo.conf ---
<VirtualHost _default_:80>
OIDCCryptoPassphrase "verylongsecret"
OIDCProviderMetadataURL
https://auth.example.com/realms/master/.well-known/openid-configuration
OIDCRedirectURI http://sogo.example.com/redirect_uri
OIDCClientID SOGo
OIDCClientSecret random_client_secret
OIDCRemoteUserClaim email
OIDCScope "email openid"
OIDCAuthNHeader x-webobjects-remote-user
OIDCXForwardedHeaders X-Forwarded-Proto X-Forwarded-Port
X-Forwarded-Host
OIDCRemoteUserClaim email
OIDCPassClaimsAs both
<Location />
AuthType openid-connect
Require valid-user
</Location>
<Proxy http://127.0.0.1:20000/SOGo>
<IfModule headers_module>
# Add Basic Authorization
RequestHeader set "x-webobjects-auth-type" "Basic"
# Combine Username and Password wth a colon ':' only when a
valid access_token is available
RequestHeader set Authorization
"%{OIDC_CLAIM_email}e:%{OIDC_access_token}e" env=OIDC_access_token
# Add the plain Text 'Basi ' and the base64 encode
Username:access_token to the Authorization header
RequestHeader set Authorization "expr=Basic
%{base64:%{HTTP:Authorization}}"
--- /etc/apache2/sites-available/sogo.conf ---
I removed every SOGoSAML2* config setting from /etc/sogo/sogo.conf and
changed these settings:
SOGoTrustProxyAuthentication = YES;
NGImap4AuthMechanism = PLAIN;
SOGoForceExternalLoginWithEmail = YES;
You need to adjust dovecot to support the login via PLAIN. The
access_token is stored as the password in the PLAIN authentication. To
support this make these changes:
--- /etc/dovecot/conf.d/auth-oauth2.conf.ext ---
auth_mechanisms = $auth_mechanisms plain
passdb {
driver = oauth2
mechanisms = plain
args = /etc/dovecot/dovecot-oauth2.plain.conf.ext
}
---
Please note that I use local introspection_mode, you need to copy the
keys required to validate the access_token to the directory
/etc/dovecot/keys/. The required keys are logged when you enable full
debug logs.
--- /etc/dovecot/dovecot-oauth2.plain.conf.ext ---
openid_configuration_url =
https://auth.example.com/realms/master/.well-known/openid-configuration
introspection_mode = local
issuers = https://auth.example.com/realms/master
local_validation_key_dict = fs:posix:prefix=/etc/dovecot/keys/
client_id = dovecot
client_secret = random_client_secret
scope = email
username_attribute = email
username_format = %Ln
---
Since the access_token from keycloak will expire within a minute (the
default) you should change the expire time to a higher values. This is
required since I didn't know how to pass the refresh_token to dovecot
to enable dovecot to renew the access_token from time to time... I
someone has an idea I really like to know.
And one very important information. You need to configure a
SOGoUserSources to enable a successful "c_uid" lookup. So create a
table a SOGo required and just put the email from the OIDC_CLAIM_email
into the colum "c_uid". I think this table isn't really needed, maybe
I will make a patch to avoid creating such a table.
Hope this helps some!