zulip/docs/production/authentication-methods.md

140 lines
6.0 KiB
Markdown

# Authentication methods
Zulip supports several different authentications methods:
* `EmailAuthBackend` - Email/password authentication.
* `ZulipLDAPAuthBackend` - LDAP username/password authentication.
* `GoogleMobileOauth2Backend` - Google authentication.
* `GitHubAuthBackend` - GitHub authentication.
* `ZulipRemoteUserBackend` - Authentication using an existing
Single-Sign-On (SSO) system that can set REMOTE_USER in Apache.
* `DevAuthBackend` - Only for development, passwordless login as any user.
It's easy to add more; see the docs on `python-social-auth` below.
The setup documentation for most of these is simple enough that we've
included it inline in `/etc/zulip/settings.py`, right above to the
settings used to configure them. The remote user authentication
backend is more complex since it requires interfacing with a generic
third-party authentication system, and so we've documented it in
detail below.
## Adding additional methods using python-social-auth
The implementation for GitHubAuthBackend is a small wrapper around the
popular [python-social-auth] library. So if you'd like to integrate
Zulip with another authentication provider (e.g. Facebook, Twitter,
etc.), you can do this by writing a class similar to
`GitHubAuthBackend` in `zproject/backends.py` and adding a few
settings. Pull requests to add new backends are welcome; they should
be tested using the framework in `test_auth_backends.py`.
[python-social-auth]: https://python-social-auth.readthedocs.io/en/latest/
## Remote User SSO Authentication
Zulip supports integrating with a Single-Sign-On solution. There are
a few ways to do it, but this section documents how to configure Zulip
to use an SSO solution that best supports Apache and will set the
`REMOTE_USER` variable:
(0) Check that `/etc/zulip/settings.py` has
`zproject.backends.ZulipRemoteUserBackend` as the only enabled value
in the `AUTHENTICATION_BACKENDS` list, and that `SSO_APPEND_DOMAIN` is
correct set depending on whether your SSO system uses email addresses
or just usernames in `REMOTE_USER`.
Make sure that you've restarted the Zulip server since making this
configuration change.
(1) Edit `/etc/zulip/zulip.conf` and change the `puppet_classes` line to read:
```
puppet_classes = zulip::voyager, zulip::apache_sso
```
(2) As root, run `/home/zulip/deployments/current/scripts/zulip-puppet-apply`
to install our SSO integration.
(3) To configure our SSO integration, edit
`/etc/apache2/sites-available/zulip-sso.example` and fill in the
configuration required for your SSO service to set `REMOTE_USER` and
place your completed configuration file at `/etc/apache2/sites-available/zulip-sso.conf`
`zulip-sso.example` is correct configuration for using an `htpasswd`
file for `REMOTE_USER` authentication, which is useful for testing
quickly. You can set it up by doing the following:
```
/home/zulip/deployments/current/scripts/restart-server
cd /etc/apache2/sites-available/
cp zulip-sso.example zulip-sso.conf
htpasswd -c /home/zulip/zpasswd username@example.com # prompts for a password
```
and then continuing with the steps below.
(4) Run `a2ensite zulip-sso` to enable the Apache integration site.
(5) Run `service apache2 reload` to use your new configuration. If
Apache isn't already running, you may need to run `service apache2
start` instead.
Now you should be able to visit `https://zulip.example.com/` and
login via the SSO solution.
### Troubleshooting Remote User SSO
This system is a little finicky to networking setup (e.g. common
issues have to do with `/etc/hosts` not mapping
`settings.EXTERNAL_HOST` to the Apache listening on
`127.0.0.1/localhost`, for example). It can often help while debugging
to temporarily change the Apache config in
`/etc/apache2/sites-available/zulip-sso` to listen on all interfaces
rather than just `127.0.0.1` as you debug this. It can also be helpful
to change `/etc/nginx/zulip-include/app.d/external-sso.conf` to
`proxy_pass` to a more explicit URL possibly not over HTTPS when
debugging. The following log files can be helpful when debugging this
setup:
* `/var/log/zulip/{errors.log,server.log}` (the usual places)
* `/var/log/nginx/access.log` (nginx access logs)
* `/var/log/apache2/zulip_auth_access.log` (you may want to change
`LogLevel` to "debug" in the Apache config file to make this more
verbose)
Here's a summary of how the remote user SSO system works assuming
you're using HTTP basic auth; this summary should help with
understanding what's going on as you try to debug:
* Since you've configured `/etc/zulip/settings.py` to only define the
`zproject.backends.ZulipRemoteUserBackend`, `zproject/settings.py`
configures `/accounts/login/sso` as `HOME_NOT_LOGGED_IN`, which
makes `https://zulip.example.com/` (a.k.a. the homepage for the main
Zulip Django app running behind nginx) redirect to
`/accounts/login/sso` if you're not logged in.
* nginx proxies requests to `/accounts/login/sso/` to an Apache instance
listening on `localhost:8888` apache via the config in
`/etc/nginx/zulip-include/app.d/external-sso.conf` (using the upstream
`localhost:8888` defined in `/etc/nginx/zulip-include/upstreams`).
* The Apache `zulip-sso` site which you've enabled listens on
`localhost:8888` and presents the `htpasswd` dialogue; you provide
correct login information and the request reaches a second Zulip
Django app instance that is running behind Apache with with
`REMOTE_USER` set. That request is served by
`zerver.views.remote_user_sso`, which just checks the `REMOTE_USER`
variable and either logs in (sets a cookie) or registers the new
user (depending whether they have an account).
* After succeeding, that redirects the user back to `/` on port 443
(hosted by nginx); the main Zulip Django app sees the cookie and
proceeds to load the site homepage with them logged in (just as if
they'd logged in normally via username/password).
Again, most issues with this setup tend to be subtle issues with the
hostname/DNS side of the configuration. Suggestions for how to
improve this SSO setup documentation are very welcome!