Kozea / Radicale

A simple CalDAV (calendar) and CardDAV (contact) server.
https://radicale.org
GNU General Public License v3.0
3.39k stars 445 forks source link

http authentication not disabled when using --auth-type=http_x_remote_user #1119

Open grunlab opened 4 years ago

grunlab commented 4 years ago

Use case:

I'm trying to configure radicale this way:

Radicale is running into a docker container deployed on top of a kubernetes cluster. Traefik is used as edge router to access the apps running into the cluster.

Radicale config:

python3 -m radicale --server-hosts=0.0.0.0:5232 --auth-type=http_x_remote_user --storage-filesystem-folder=/mnt/collections --logging-level=info

Authentication type set to http_x_remote_user in order to:

Traefik config:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: radicale-basic-auth
  namespace: radicale-p
spec:
  basicAuth:
    secret: radicale-basic-auth
    headerField: X-Remote-User
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: radicale
  namespace: radicale-p
spec:
  entryPoints:
    - https
  routes:
  - match: Host(`<my_url>`)
    kind: Rule
    services:
    - name: radicale
      port: 80
    middlewares:
      - name: radicale-basic-auth
  tls:
    certResolver: default

Expected result:

kubectl logs radicale-7856dd6fcd-hs76h -f
[2020-11-05 22:24:42 +0100] [1] [INFO] Loaded default config
[2020-11-05 22:24:42 +0100] [1] [INFO] Skipped missing config file '/etc/radicale/config'
[2020-11-05 22:24:42 +0100] [1] [INFO] Skipped missing config file '/home/k8s/.config/radicale/config'
[2020-11-05 22:24:42 +0100] [1] [INFO] Loaded arguments
[2020-11-05 22:24:42 +0100] [1] [INFO] Starting Radicale
[2020-11-05 22:24:42 +0100] [1] [INFO] auth type is 'radicale.auth.http_x_remote_user'
[2020-11-05 22:24:42 +0100] [1] [INFO] storage type is 'radicale.storage.multifilesystem'
[2020-11-05 22:24:42 +0100] [1] [INFO] rights type is 'radicale.rights.owner_only'
[2020-11-05 22:24:42 +0100] [1] [INFO] web type is 'radicale.web.internal'
[2020-11-05 22:24:42 +0100] [1] [INFO] Listening on '[0.0.0.0]:5232'
[2020-11-05 22:24:42 +0100] [1] [INFO] Radicale server ready
[2020-11-05 22:24:55 +0100] [1/Thread-7] [INFO] GET request for '/' received from '10.44.0.0' (forwarded by 10.36.0.0) using 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0'
[2020-11-05 22:24:55 +0100] [1/Thread-7] [INFO] Successful login: 'adrien'
[2020-11-05 22:24:55 +0100] [1/Thread-7] [INFO] GET response status for '/' in 0.062 seconds: 302 Found
[2020-11-05 22:24:55 +0100] [1/Thread-8] [INFO] GET request for '/.web' received from '10.44.0.0' (forwarded by 10.36.0.0) using 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0'
[2020-11-05 22:24:55 +0100] [1/Thread-8] [INFO] Successful login: 'adrien'
[2020-11-05 22:24:55 +0100] [1/Thread-8] [INFO] GET response status for '/.web' in 0.033 seconds: 302 Found
[2020-11-05 22:24:55 +0100] [1/Thread-9] [INFO] GET request for '/.web/css/main.css' received from '10.44.0.0' (forwarded by 10.36.0.0) using 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0'
[2020-11-05 22:24:55 +0100] [1/Thread-9] [INFO] Successful login: 'adrien'
[2020-11-05 22:24:55 +0100] [1/Thread-9] [INFO] GET response status for '/.web/css/main.css' in 0.040 seconds: 200 OK

Did i missed something into the configuration or is there a bug somewhere !?

Thank you for your support

aerusso commented 3 years ago

I also ran into this problem. I worked around it by just curl-ing the CalDAV and CardDAV commands.

jtorrex commented 3 years ago

Same case here as detailed by @grunlab.

timakro commented 3 years ago

Seems like you can log in with any username and password. And even though it says "logged in as xyz", the effective user is always the one from X-Remote-User. No security issue here but confusing UX.

chris2fr commented 2 years ago

Yes, confusing GUI.

gardiol commented 10 months ago

Agreed, some thing happens here. User seems logged, but web ui requires another login (useless). Works tough. Just confusing and ugly.

57194 commented 4 months ago

I'm not sure exactly where all in the code it would need to be updated, but basically anywhere in the code the login page would be called, I think there just needs to be a check of the config file and just send the user in if they have the config option set and the right header. Would probably need another "passwordless" code path added, since most of the login code looks like it all requires a (username, password) tuple.

pbiering commented 3 months ago

Hi all, I need more details to understand what happens when and what is unexpected? Would be good if one can provide related request+response headers.

pbiering commented 3 months ago

I ran some analysis and assume the issue is related to WebUI only which still after passing Basic Auth on a reverse proxy, which protects e.g. complete /radicale/* is displaying the login screen and also requires credentials to work.

This is somehow by nature as the WebUI is client-only Javascript implementation and requires the credentials to run the C*DAV-requests.

@MatthewHana : is there any chance that the WebUI is able to take advantage of already provided BasicAuth of the initial request, so to say "borrow" for it's own requests generated in Javascript the BasicAuth from the browser session?

Final goal would be bypassing the login screen if surrounding BasicAuth is already provided and tested by Javascript successfully in case of "forbidden" fallback to login screen.

A workaround would be excluding the .web from BasicAuth, but I haven't tested whether this is supported by web servers to exclude a sub-path from BasicAuth while the main path is protected. If not supported, one can test internal redirects and expose the WebUI on a different main path outside BasicAuth - but here potentially some base URI must be adjusted.

gardiol commented 3 months ago

Could this info be of any use? https://www.authelia.com/integration/proxies/support/#standard

ALso check the NGINX configiration files for authelia here https://www.authelia.com/integration/proxies/nginx/#authelia-authrequestconf and here https://www.authelia.com/integration/proxies/nginx/#authelia-location-basicconf

It already just works with proxy auth, i guess it's only matter of checking the right headers?

selenith commented 2 months ago

Hi, I made a quick and dirty hack that gets the username from the server environment variables and submits the form when the page is opened on my server.

If it helps, here's how I did it.

I've created a php page in the same vhost that returns the user name present in the variable $_SERVER['REMOTE_USER'] in json like this: {“user”:“”}

My php code :

//file userinfos.php
<?php

$user_data = ['user'=>'not_connected'];
if(!empty($_SERVER["REMOTE_USER"])){

            $user_data['user'] =$_SERVER["REMOTE_USER"];
}

echo(json_encode($user_data));
?>

I modified the fn.js file in two places:

}



With a little tweaking of the nginx config, I also got it to work with p12 certificates for authentication via HTTPS without password. If anyone is interested I can detail the configuration.