New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single Sign On for Zammad #1192

Open
jaeger13 opened this Issue Jun 20, 2017 · 24 comments

Comments

Projects
None yet
@jaeger13
Copy link

jaeger13 commented Jun 20, 2017

Infos:

  • Used Zammad version: latest
  • Used Zammad installation source: rpm
  • Operating system: CentOS 7
  • Browser + version: Firefox latest

This is a question regarding Single Sign On. We are using a Microsoft Active Directory in our company and the login works fine with ldap-sync.
Im wondering if SSO would be possible. I already tried to set it up using nginx, but it just won't work :-(

Is there an easy way to do it? Maybe one of you already set up Zammad with SSO? Would be nice if someone has an instruction or some examples how to implement it.

Thank you in advance.

@rkaldung

This comment has been minimized.

Copy link
Collaborator

rkaldung commented Jun 20, 2017

Hi @jaeger13,

This is possible of course. But you have to use Apache httpd with mod_auth_kerb, with a config like this:

<LocationMatch "/auth/sso">
  SSLRequireSSL
  AuthType Kerberos
  AuthName "Your Zammad"
  KrbMethodNegotiate On
  KrbMethodK5Passwd On
  KrbAuthRealms YOUR.REALM
  KrbLocalUserMapping on
  KrbServiceName HTTP/zammad.your.domain@YOUR.REALM
  Krb5KeyTab /etc/httpd/zammad.keytab
  require valid-user
</LocationMatch>

Depending on the choosen uid attribute (ist sAMAccountName in the example above) it will work out of the box.

And you have to configure Apache as the reverse proxy instead of nginx.

As long as the auth module returns the authenticated username in the environment variable REMOTE_USER or HTTP_REMOTE_USER it is possible to use other modules like auth_mellon etc.

hth, Roy

@jaeger13

This comment has been minimized.

Copy link

jaeger13 commented Jun 20, 2017

Hey @rkaldung ,

thank you for your fast answer. I will try it with Apache and your instructions :-)
Although i wished there would be a way to do it with nginx :-(

Thanks!

@rkaldung

This comment has been minimized.

Copy link
Collaborator

rkaldung commented Jun 20, 2017

Hi @jaeger13,

There is a way with nginx, but without testing at the moment. @martini Your two cents on this?

@scimitar4444

This comment has been minimized.

Copy link

scimitar4444 commented Jun 29, 2017

Hi @rkaldung

Can you describe the way with NGINX? That would also interest me very much. Thanks.

@martini

This comment has been minimized.

Copy link
Collaborator

martini commented Jun 29, 2017

Hi @scimitar4444

@rkaldung means an implementation on rails level like https://github.com/jgraichen/omniauth-kerberos - but this need to be implemented in Zammad first. 🤖

-Martin

@rkaldung

This comment has been minimized.

Copy link
Collaborator

rkaldung commented Jun 29, 2017

@martini It's always only one commit away 😜

@MenneBakker

This comment has been minimized.

Copy link

MenneBakker commented Sep 15, 2017

I've been trying to get SSO working using your instructions. However browsing http://myserver.mydom.local/auth/sso is taking me back to the login page . . . am I missing something ?

@pikachuprof

This comment has been minimized.

Copy link

pikachuprof commented Dec 20, 2017

Trying to use (Stanford) Webauth (and ldap user) results in same error, after successful login in SSO I get the zammad prompt to login.
Using: Ubuntu 16.04; Zammad 2.2.0; Apache, MariaDB; (REMOTE_USER is set by webauth)

@rkaldung do you know sth. new?

@pikachuprof

This comment has been minimized.

Copy link

pikachuprof commented Dec 21, 2017

Found a workaround:

Problem: The needed module in lib/sso/env.rb is called without the needed request.env from PUMA, so 'REMOTE_USER' is not available.

Workaround:
Add 'REMOTE_USER' from the request.env to ENV in 'zammad/app/controllers/sessions_controller.rb' inside function 'create_sso'

   # export required environment variables for sso
   ENV['REMOTE_USER'] = request.env['REMOTE_USER']
   ENV['HTTP_REMOTE_USER'] = request.env['HTTP_REMOTE_USER']

@martini could this be a problem with a newer version of PUMA?

EDIT: You have to add a corresponding rule for setting the header-field in httpd.conf to get it working:

RequestHeader merge REMOTE_USER %{REMOTE_USER}s
@cohausz

This comment has been minimized.

Copy link

cohausz commented Jan 5, 2018

Edit 2018-01-08:
Everything works now with the workaround from pikachuprof. It was a typo in the /etc/krb5.conf Config.

Infos:
Used Zammad version: latest
Used Zammad installation source: rpm
Operating system: CentOS 7
Browser + version: Firefox latest

Apache Server Config:
<VirtualHost *:443>
    ServerName ***
    ServerAdmin ***

    DocumentRoot "/opt/zammad/public"

    <IfModule !mod_auth_kerb.c>
        LoadModule auth_kerb_module /usr/lib64/httpd/modules/mod_auth_kerb.so
    </IfModule>

    ProxyRequests Off
    ProxyPreserveHost On

    <Proxy localhost:3000>
        Require local
    </Proxy>

    ProxyPass /assets !
    ProxyPass /favicon.ico !
    ProxyPass /robots.txt !
    ProxyPass /ws ws://localhost:6042/
    ProxyPass / http://localhost:3000/

    <Directory />
        Options FollowSymLinks
        AllowOverride None
    </Directory>

    <Directory "/opt/zammad/public">
        Options FollowSymLinks
        Require all granted
    </Directory>

    <Location "/auth/sso">
        Order allow,deny
        Allow from all

        AuthType Kerberos
        AuthName "Ticketsystem Kerberos Login"
        KrbServiceName HTTP
        KrbMethodNegotiate on
        KrbMethodK5Passwd on
        KrbLocalUserMapping off
        KrbSaveCredentials on

        Require valid-user

        # Environment specific: Path to the keytab and the realm
        Krb5Keytab /etc/kerberos.keytab
        KrbAuthRealm ***
    </Location>
        
    SSLEngine on
    SSLCertificateFile /etc/pki/tls/certs/***
    SSLCertificateKeyFile /etc/pki/tls/private/***

    ErrorLog "logs/***-error_log"
    CustomLog "logs/***-access_log" common
</VirtualHost>

When I open https://***/auth/sso and "KrbLocalUserMapping on" my browser show the following error:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator at admin@*** to inform them of the time this error occurred, and the actions you performed just before this error.
More information about this error may be available in the server error log.

If I set "KrbLocalUserMapping off" my browser is redirected to https://***/#login

I try to set "RequestHeader merge REMOTE_USER %{REMOTE_USER}s" but nothing changes.

Hope someone can help!

@pikachuprof

This comment has been minimized.

Copy link

pikachuprof commented Feb 23, 2018

We have added another little workaround:

RewriteEngine   On
RewriteCond     %{HTTP_COOKIE} !^.*zammad_session.*$
RewriteRule     ^/$ https://%{SERVER_NAME}/auth/sso [R,L]

These lines in Apache-config redirect '/' to '/auth/sso' only as long as no zammad cookie is set. This allows redirection to SSO login page without creating an endless loop resulting in 'Internal Server Error'.

@EDVLeer

This comment has been minimized.

Copy link

EDVLeer commented Feb 27, 2018

I can't seem to get it working. . . apache logs show my username for /auth/sso then my request get redirected to / and my username is gone. . . maybe I made a mistake in editing the create_sso function !? Can someone give me a hint ?

@muhammadn muhammadn self-assigned this Feb 27, 2018

@muhammadn

This comment has been minimized.

Copy link
Contributor

muhammadn commented Feb 27, 2018

@pikachuprof I had worked on an implementation using omniauth-kerberos.

However, my implementation requires you to login each time you wish to access Zammad (using your Kerberos credentials of course) instead of using the "kerberos ticket" which is already generated by the user's machine. (eg. from kinit or any other "kerberos ticketing client")

I hope this is fine for basic login using kerberos to avoid hacky situations. 😊

Though i feel that for advanced configurations with 'one-time login/authentication' (eg. using kinit once and authenticate) and then you ssh/login to zammad/internal websites/ftp all the servers without authenticating anymore (SPNEGO/GSSAPI) can only be done by fully configuring the frontend webserver (like Apache) which you are doing right now.

screen shot 2018-02-27 at 8 37 57 pm

screen shot 2018-02-27 at 8 48 00 pm

@pikachuprof

This comment has been minimized.

Copy link

pikachuprof commented Mar 5, 2018

@muhammadn we use a Kerberos based Single-Sign-On Service called Stanford Webauth (mod_auth_webauth). It allows login in via password (in browser) (and sets a cookie containing a Kerberos-Token for SSO) but does not transfer user-passwords to the service - only to our 'WebKDC'.

The authentication has to be done by Apache in this setup of course - but Zammad should use the REMOTE_USER variable to allow any of those "webserver-auth" mechanisms to work (or sth. similar?), as well as providing a method for breaking out of the "login-loop" without relying on checking for a cookie, which seems a little unreliable.

@muhammadn

This comment has been minimized.

Copy link
Contributor

muhammadn commented Mar 5, 2018

@pikachuprof I have pushed my implementation at muhammadn@7e8e01b

That implementation is not officially a zammad feature but just for you to try out using omniauth-kerberos library. You won't need to configure apache with kerberos support as everything will he handled by Zammad (it is rails-level implementation) and won't need REMOTE_USER in the header or even mod_auth_webauth.

All you need is to have your krb5.conf properly setup.

example:

[logging]
    default = FILE:/var/log/krb5.log

[libdefaults]
    default_realm = ZAMMAD.COM
    kdc_timesync = 1
    ccache_type = 4
    forwardable = true
    proxiable = true

[realms]
    ZAMMAD.COM = {
        kdc = kdc.zammad.com
        admin_server = kdc.zammad.com
        default_domain = zammad.com
    }

[domain_realm]
    .zammad.com = ZAMMAD.COM
    zammad.com = ZAMMAD.COM

You can post any issues about that at https://github.com/muhammadn/zammad/issues instead for that since it is not official implementation.

However, do note that to login with zammad you need to have the realm in uppercase: eg: zaihan@ZAMMAD.COM

@MenneBakker

This comment has been minimized.

Copy link

MenneBakker commented Mar 22, 2018

Any chance that we'll be able to use existing kerberos tickets for authentication ? Our users are used to such a comfortable solution and I've got no chance to switch to zammad until I get real SSO working.

@FGIKCM

This comment has been minimized.

Copy link

FGIKCM commented Jul 10, 2018

Same problem for me. I managed to make an SSO connection from Apache side (which populate REMOTE_USER) with 2 methods (Kerberos & X509 SSL Client certificate). And my users accounts are well populated, with the Zammad LDAP plugin.

  • As @EDVLeer when I reach /auth/sso I see the user login in the apache log (so it works), but I come back on the login screen again.
  • I tried the hack of writing in zammad/app/controllers/sessions_controller.rb (@pikachuprof hack), but as @EDVLeer, either I put it in a wrong place, either the code changed afterward and we must put this somewhere else now.
  • I tried the @pikachuprof hack of not redirecting to / if there is a cookie, with no luck
  • I'm now out of ideas :D

So...

  • must I activate a plugin or something in Zammad to make it work?
  • Is it a bug in the code? (Prehaps yes, if we have to change source code)
  • Is the url /auth/sso still valid in latest releases?
  • Or is there a official doc on how to implement SSO with Zammad?

Notes:

Configuration for Kerberos

<Location "/auth/sso">
	Options FollowSymLinks
	AuthType		Kerberos
	AuthName		"My Name"
	KrbMethodNegotiate	On
	# 'Off' to force users having a valid kerberos ticket, and not prompting for a login/pass
	KrbMethodK5Passwd	Off
	KrbAuthRealms		MY-DOMAIN.FR
	Krb5KeyTab		/etc/krb5.keytab
	KrbLocalUserMapping	On
	KrbServiceName		HTTP
	Require valid-user
</Location>

Configuration for X509 SSL certificate

Note: you must append your CA public certificate (.crt) in your Apache 'CA Bundle' file (SSLCACertificateFile) so that Apache can check if clients certificates are OK

# Let this before <Location> to get the certificate at the first connect, and avoid SSL renegotiation
# when we now the real url
SSLVerifyClient     require
<Location "/auth/sso">
	Options FollowSymLinks
	SSLRequireSSL
	SSLVerifyDepth		1    # Depend of your config. Can be higher
	Require expr %{SSL_CLIENT_I_DN_CN} in {'MY CA NAME'}
	SSLOptions		+StdEnvVars
	# Get the 'firstname.lastname' part of the corporate email, and populate REMOTE_USER
	RewriteEngine		On
	RewriteCond		%{SSL:SSL_CLIENT_S_DN_Email} ^(.+)@.+$
	RewriteRule		.* - [E=REMOTE_USER:%1]
	RequestHeader set REMOTE_USER %{REMOTE_USER}e
</Location>
@schmanat

This comment has been minimized.

Copy link

schmanat commented Jul 24, 2018

I could "solve" the SSO Issue, I thinks its definitely not the perfect way but it works.

My envirentment is the latest zammad version (2.5) with Apache2 2.4 with Postgres. After the configuration of SSO with mod_auth_kerb I have to do the following things.

I configured LDAP to sync our employees. I mapped the SAMACOUNTNAME to the login name. For example my Windows Username ist schman. So I could login with this username (not with the e-mail).

After that I have edited the sessions_controller.rb and add the following line (on line 173)

ENV['HTTP_REMOTE_USER']=request.env['HTTP_REMOTE_USER']

so Zammad knows the HTTP_REMOTE_USER. After that the login doesn't work. Because the value of HTTP_REMOTE_USER is now schman@DOMAIN.AT. To fix that i add the following line to my vHost configuration.

RequestHeader edit REMOTE_USER "@DOMAIN.AT" ""

After Restarting (Apache2 and Zammad) I could login vis SSO with http://zammad.domain.at/auth/sso

If someone speek german, I have write a little post on my blog.

@pikachuprof

This comment has been minimized.

Copy link

pikachuprof commented Jul 24, 2018

@schmanat how did you solve the "login-loop" or do you let the user use the "/auth/sso" URL?

@schmanat

This comment has been minimized.

Copy link

schmanat commented Jul 24, 2018

For now, the users get the /auth/sso url.

But this is the next thing I would like to dig in. Didn't work the workarround of your answer a few comments above (RewriteRule)?

@pikachuprof

This comment has been minimized.

Copy link

pikachuprof commented Jul 25, 2018

Yes it did, but it is pretty unreliable.

@jeremyj563

This comment has been minimized.

Copy link

jeremyj563 commented Aug 9, 2018

Thanks everyone for your work on this and for documenting what you've done. Unfortunately I am at a loss. As others have experienced, I too am being redirected to the login page after hitting the "auth/sso" endpoint. Here is everything I've done:

  • installed Zammad on Debian 9 (stretch)
  • configured ldap integration (mapped samaccountname -> login)
  • confirmed able to login with AD username/password
  • created service account in AD (simply called zammad)
  • created keytab mapped to zammad service account
  • configured kerberos client/realm (in /etc/krb5.conf)
  • verified kerberos environment with kinit
  • verified that keytab is working (able to get TGT from KDC)
  • configured Apache2 vhost (as explained by cohausz)
  • modified sessions_controller.rb (as explained by pikachuprof)
  • added header rule to vhost config (as explained by pikachuprof)

I also tried the solutions offered by schmant but nothing seems to help.

Below are my Apache2 logs. As you can see the user is being passed through... How can I verify that the environment variables REMOTE_USER / HTTP_REMOTE_USER are being set correctly? Are there any other troubleshooting steps I can try?

zammad.example.com:443 10.1.4.197 - - [09/Aug/2018:09:39:23 -0500] "GET /auth/sso HTTP/1.1" 401 855 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
zammad.example.com:443 10.1.4.197 - user@EXAMPLE.COM [09/Aug/2018:09:39:23 -0500] "GET /auth/sso HTTP/1.1" 302 969 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
zammad.example.com:443 10.1.4.197 - - [09/Aug/2018:09:39:23 -0500] "GET / HTTP/1.1" 200 1757 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
zammad.example.com:443 10.1.4.197 - - [09/Aug/2018:09:39:23 -0500] "POST /api/v1/signshow HTTP/1.1" 200 15874 "https://zammad.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
zammad.example.com:443 10.1.4.197 - - [09/Aug/2018:09:39:24 -0500] "GET /api/v1/translations/lang/en-us?_=1533825563736 HTTP/1.1" 200 720 "https://zammad.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
zammad.example.com:443 10.1.4.197 - - [09/Aug/2018:09:39:24 -0500] "GET /assets/images/fed16b83d2e87ea36cea961d6d8a2101.png HTTP/1.1" 304 210 "https://zammad.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" 
@Fischmue

This comment has been minimized.

Copy link

Fischmue commented Sep 3, 2018

Hello there,

i have the same error as @jeremyj563.

Is there any solution to login with SSO?

Thanks for reply

@lobiman

This comment has been minimized.

Copy link

lobiman commented Jan 13, 2019

I'm interested in SSO too.

It would be an option to implement Azure AD for SSO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment