2020-03-04 22:10:58 +00:00
# External Authentication
2020-04-01 21:25:23 +00:00
To enable external authentication, you must set the absolute path of your authentication program or an HTTP URL using the `external_auth_hook` key in your configuration file.
2020-03-04 22:10:58 +00:00
The external program can read the following environment variables to get info about the user trying to authenticate:
- `SFTPGO_AUTHD_USERNAME`
2021-03-26 14:19:01 +00:00
- `SFTPGO_AUTHD_USER` , STPGo user serialized as JSON, empty if the user does not exist within the data provider
2020-08-04 16:03:28 +00:00
- `SFTPGO_AUTHD_IP`
2020-08-12 14:15:12 +00:00
- `SFTPGO_AUTHD_PROTOCOL` , possible values are `SSH` , `FTP` , `DAV`
2020-03-04 22:10:58 +00:00
- `SFTPGO_AUTHD_PASSWORD` , not empty for password authentication
- `SFTPGO_AUTHD_PUBLIC_KEY` , not empty for public key authentication
- `SFTPGO_AUTHD_KEYBOARD_INTERACTIVE` , not empty for keyboard interactive authentication
2021-02-28 11:10:40 +00:00
- `SFTPGO_AUTHD_TLS_CERT` , TLS client certificate PEM encoded. Not empty for TLS certificate authentication
2020-03-04 22:10:58 +00:00
Previous global environment variables aren't cleared when the script is called. The content of these variables is _not_ quoted. They may contain special characters. They are under the control of a possibly malicious remote user.
2021-03-26 14:19:01 +00:00
The program can inspect the SFTPGo user, if it exists, using the `SFTPGO_AUTHD_USER` environment variable.
The program must write, on its standard output:
- a valid SFTPGo user serialized as JSON if the authentication succeeds. The user will be added/updated within the defined data provider
- an empty string, or no response at all, if authentication succeeds and the existing SFTPGo user does not need to be updated
- a user with an empty username if the authentication fails
2020-04-01 21:25:23 +00:00
If the hook is an HTTP URL then it will be invoked as HTTP POST. The request body will contain a JSON serialized struct with the following fields:
- `username`
2020-08-04 16:03:28 +00:00
- `ip`
2021-03-26 14:19:01 +00:00
- `user` , STPGo user serialized as JSON, omitted if the user does not exist within the data provider
2020-08-12 14:15:12 +00:00
- `protocol` , possible values are `SSH` , `FTP` , `DAV`
2020-04-01 21:25:23 +00:00
- `password` , not empty for password authentication
- `public_key` , not empty for public key authentication
- `keyboard_interactive` , not empty for keyboard interactive authentication
2021-02-28 11:10:40 +00:00
- `tls_cert` , TLS client certificate PEM encoded. Not empty for TLS certificate authentication
2020-04-01 21:25:23 +00:00
2021-03-26 14:19:01 +00:00
If authentication succeeds the HTTP response code must be 200 and the response body can be:
- a valid SFTPGo user serialized as JSON. The user will be added/updated within the defined data provider
- empty, the existing SFTPGo user does not need to be updated
If the authentication fails the HTTP response code must be != 200.
2020-04-01 21:25:23 +00:00
2021-03-26 14:19:01 +00:00
Actions defined for users added/updated will not be executed in this case and an already logged in user with the same username will not be disconnected.
2020-08-12 14:42:38 +00:00
2020-04-26 21:29:09 +00:00
The program hook must finish within 30 seconds, the HTTP hook timeout will use the global configuration for HTTP clients.
2020-04-01 21:25:23 +00:00
This method is slower than built-in authentication, but it's very flexible as anyone can easily write his own authentication hooks.
You can also restrict the authentication scope for the hook using the `external_auth_scope` configuration key:
2020-03-04 22:10:58 +00:00
2021-02-28 11:10:40 +00:00
- `0` means all supported authentication scopes. The external hook will be used for password, public key, keyboard interactive and TLS certificate authentication
2020-08-19 17:36:12 +00:00
- `1` means passwords only
- `2` means public keys only
- `4` means keyboard interactive only
2021-02-28 11:10:40 +00:00
- `8` means TLS certificate only
2020-03-04 22:10:58 +00:00
You can combine the scopes. For example, 3 means password and public key, 5 means password and keyboard interactive, and so on.
Let's see a very basic example. Our sample authentication program will only accept user `test_user` with any password or public key.
2020-06-15 21:46:11 +00:00
```shell
2020-03-04 22:10:58 +00:00
#!/bin/sh
if test "$SFTPGO_AUTHD_USERNAME" = "test_user"; then
echo '{"status":1,"username":"test_user","expiration_date":0,"home_dir":"/tmp/test_user","uid":0,"gid":0,"max_sessions":0,"quota_size":0,"quota_files":100000,"permissions":{"/":["*"],"/somedir":["list","download"]},"upload_bandwidth":0,"download_bandwidth":0,"filters":{"allowed_ip":[],"denied_ip":[]},"public_keys":[]}'
else
echo '{"username":""}'
fi
```
2021-03-01 21:22:05 +00:00
The structure for SFTPGo users can be found within the [OpenAPI schema ](../httpd/schema/openapi.yaml ).
2020-04-26 12:48:32 +00:00
An example authentication program allowing to authenticate against an LDAP server can be found inside the source tree [ldapauth ](../examples/ldapauth ) directory.
An example server, to use as HTTP authentication hook, allowing to authenticate against an LDAP server can be found inside the source tree [ldapauthserver ](../examples/ldapauthserver ) directory.
2020-04-11 20:30:41 +00:00
If you have an external authentication hook that could be useful to others too, please let us know and/or please send a pull request.