add support for http_remote_user
This commit is contained in:
@@ -902,8 +902,15 @@ Available types are:
|
||||
Requires validation, otherwise clients can supply the header themselves,
|
||||
which then is unconditionally trusted.
|
||||
|
||||
* `http_remote_user` _(>= 3.5.9)_
|
||||
Takes the username from the Remote-User HTTP header `HTTP_REMOTE_USER` and disables
|
||||
Radicale's internal HTTP authentication. This can be used to provide the
|
||||
username from a reverse proxy which authenticated the client upfront.
|
||||
Requires validation, otherwise clients can supply the header themselves,
|
||||
which then is unconditionally trusted.
|
||||
|
||||
* `http_x_remote_user`
|
||||
Takes the username from the `X-Remote-User` HTTP header and disables
|
||||
Takes the username from the X-Remote-User HTTP header `HTTP_X_REMOTE_USER` and disables
|
||||
Radicale's internal HTTP authentication. This can be used to provide the
|
||||
username from a reverse proxy which authenticated the client upfront.
|
||||
Requires validation, otherwise clients can supply the header themselves,
|
||||
|
||||
2
config
2
config
@@ -63,7 +63,7 @@
|
||||
[auth]
|
||||
|
||||
# Authentication method
|
||||
# Value: none | htpasswd | remote_user | http_x_remote_user | dovecot | ldap | oauth2 | pam | denyall
|
||||
# Value: none | htpasswd | remote_user | http_remote_user | http_x_remote_user | dovecot | ldap | oauth2 | pam | denyall
|
||||
#type = denyall
|
||||
|
||||
# Cache logins for until expiration time
|
||||
|
||||
@@ -275,7 +275,7 @@ class Application(ApplicationPartDelete, ApplicationPartHead,
|
||||
logger.debug("Called by reverse proxy, remove base prefix %r from path: %r => %r", base_prefix, path, path_new)
|
||||
path = path_new
|
||||
else:
|
||||
if self._auth_type in ['remote_user', 'http_x_remote_user'] and self._web_type == 'internal':
|
||||
if self._auth_type in ['remote_user', 'http_remote_user', 'http_x_remote_user'] and self._web_type == 'internal':
|
||||
logger.warning("Called by reverse proxy, cannot remove base prefix %r from path: %r as not matching (may cause authentication issues using internal WebUI)", base_prefix, path)
|
||||
else:
|
||||
logger.debug("Called by reverse proxy, cannot remove base prefix %r from path: %r as not matching", base_prefix, path)
|
||||
|
||||
@@ -23,7 +23,7 @@ Authentication module.
|
||||
|
||||
Authentication is based on usernames and passwords. If something more
|
||||
advanced is needed an external WSGI server or reverse proxy can be used
|
||||
(see ``remote_user`` or ``http_x_remote_user`` backend).
|
||||
(see ``remote_user``, ``http_remote_user`` or ``http_x_remote_user`` backend).
|
||||
|
||||
Take a look at the class ``BaseAuth`` if you want to implement your own.
|
||||
|
||||
@@ -40,6 +40,7 @@ from radicale import config, types, utils
|
||||
from radicale.log import logger
|
||||
|
||||
INTERNAL_TYPES: Sequence[str] = ("none", "remote_user", "http_x_remote_user",
|
||||
"http_remote_user",
|
||||
"denyall",
|
||||
"htpasswd",
|
||||
"ldap",
|
||||
@@ -59,6 +60,7 @@ CACHE_LOGIN_TYPES: Sequence[str] = (
|
||||
|
||||
INSECURE_IF_NO_LOOPBACK_TYPES: Sequence[str] = (
|
||||
"remote_user",
|
||||
"http_remote_user",
|
||||
"http_x_remote_user",
|
||||
)
|
||||
|
||||
|
||||
36
radicale/auth/http_remote_user.py
Normal file
36
radicale/auth/http_remote_user.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# This file is part of Radicale - CalDAV and CardDAV server
|
||||
# Copyright © 2025-2025 Peter Bieringer <pb@bieringer.de>
|
||||
#
|
||||
# This library is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Radicale. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Authentication backend that takes the username from the
|
||||
``HTTP_REMOTE_USER`` header.
|
||||
|
||||
It's intended for use with a reverse proxy. Be aware as this will be insecure
|
||||
if the reverse proxy is not configured properly.
|
||||
|
||||
"""
|
||||
|
||||
from typing import Tuple, Union
|
||||
|
||||
from radicale import types
|
||||
from radicale.auth import none
|
||||
|
||||
|
||||
class Auth(none.Auth):
|
||||
|
||||
def get_external_login(self, environ: types.WSGIEnviron) -> Union[
|
||||
Tuple[()], Tuple[str, str]]:
|
||||
return environ.get("HTTP_REMOTE_USER", ""), ""
|
||||
@@ -263,6 +263,23 @@ class TestBaseAuthRequests(BaseTest):
|
||||
href_element = prop.find(xmlutils.make_clark("D:href"))
|
||||
assert href_element is not None and href_element.text == "/test/"
|
||||
|
||||
def test_http_remote_user(self) -> None:
|
||||
self.configure({"auth": {"type": "http_remote_user"}})
|
||||
_, responses = self.propfind("/", """\
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<propfind xmlns="DAV:">
|
||||
<prop>
|
||||
<current-user-principal />
|
||||
</prop>
|
||||
</propfind>""", HTTP_REMOTE_USER="test")
|
||||
assert responses is not None
|
||||
response = responses["/"]
|
||||
assert not isinstance(response, int)
|
||||
status, prop = response["D:current-user-principal"]
|
||||
assert status == 200
|
||||
href_element = prop.find(xmlutils.make_clark("D:href"))
|
||||
assert href_element is not None and href_element.text == "/test/"
|
||||
|
||||
def test_http_x_remote_user(self) -> None:
|
||||
self.configure({"auth": {"type": "http_x_remote_user"}})
|
||||
_, responses = self.propfind("/", """\
|
||||
|
||||
Reference in New Issue
Block a user