Skip to content
This repository has been archived by the owner on Feb 16, 2023. It is now read-only.

Feature: authentication via HTTP_REMOTE_USER #260

Merged
merged 3 commits into from Jan 6, 2021
Merged

Feature: authentication via HTTP_REMOTE_USER #260

merged 3 commits into from Jan 6, 2021

Conversation

shamoon
Copy link
Contributor

@shamoon shamoon commented Jan 3, 2021

This PR adds support for authenticating via HTTP_REMOTE_USER which is set by some SSO applications, in my case, Authelia. Also see #142 (comment) . This PR adds:

  • A new config variable PAPERLESS_ENABLE_HTTP_REMOTE_USER to enable this feature, by default its disabled
  • A very simple authentication class
  • Basic documentation

Its pretty simple really but wanted to run it by you @jonaswinkler first. Thanks as always for any help / feedback!

@shamoon shamoon changed the title Feature: enable authentication via HTTP_REMOTE_USER Feature: authentication via HTTP_REMOTE_USER Jan 3, 2021
@jonaswinkler
Copy link
Owner

jonaswinkler commented Jan 3, 2021

https://docs.djangoproject.com/en/3.1/howto/auth-remote-user/

I think this is it? Better to use built-in stuff than making that yourself.

@shamoon
Copy link
Contributor Author

shamoon commented Jan 3, 2021

Yea sorry I saw that and used it as reference (actually more this one: https://www.django-rest-framework.org/api-guide/authentication/ ) but at least for Authelia it’s HTTP_ not just REMOTE_USER, I tested the built-in classes.

One thought that occurs to me now is I can change this class to allow for both if you’d prefer that.

@jonaswinkler
Copy link
Owner

jonaswinkler commented Jan 4, 2021

https://docs.djangoproject.com/en/3.1/howto/auth-remote-user/#configuration, see

If your authentication mechanism uses a custom HTTP header and not REMOTE_USER, you can subclass RemoteUserMiddleware and set the header attribute to the desired request.META key.

I haven't tested that, but the documentation reads as if this should be possible.

You will also need to configure auth for both the django app as well as the rest framework, but apparently RemoteUserAuthentication seems to be using the django authentication classes (https://www.django-rest-framework.org/api-guide/authentication/#remoteuserauthentication), so that should work. Again, just glanced over the documentation.

@shamoon
Copy link
Contributor Author

shamoon commented Jan 4, 2021

Aha thanks for explaining, I didn't quite realize authentication needs to be setup for both. I changed this to use RemoteUserAuthentication and just extend RemoteUserMiddleware with the different header. I still left it all behind the flag, too.

I think this should be good, please let me know if you have any more thoughts, and thanks!

@shamoon shamoon marked this pull request as ready for review January 4, 2021 05:24
@jonaswinkler
Copy link
Owner

Works. I tried to get authelia running to see this in action, but decided to just set the HTTP_REMOTE_USER env variable for testing.

What are the chances that users need the evironment variable to actually be REMOTE_USER?

What about logout, how is that handled with authelia?

@shamoon
Copy link
Contributor Author

shamoon commented Jan 6, 2021

Yea there are other SSO applications that do use REMOTE_USER but many of them are using OIDC or something else. Im not sure if its worth enabling that as well or better to just wait to see if people request it. The nice thing about Authelia is its so easy to setup and it uses forwardAuth which is totally enough for many home server setups (IMHO).

Logout is done via Authelia at the same URL you setup to login, e.g. login.example.com

@jonaswinkler jonaswinkler merged commit b17d9f8 into jonaswinkler:dev Jan 6, 2021
@lenaxia
Copy link

lenaxia commented Mar 2, 2021

@shamoon @jonaswinkler I just want to say thanks very much for doing this, forward auth is absolutely something that I wanted.

However I'm having trouble getting it working. I have Forward auth working with grafana using Remote-User, but can't seem to get it working simultaneously with paperless. Does this have to do with the fact that Grafana uses Remote-User?

grafana.ini

[auth.proxy]
enabled = true
header_name = Remote-User
header_property = username
auto_sign_up = false 
sync_ttl = 60
whitelist = 172.24.0.7/32
headers = Email:X-User-Email, Name:X-User-Name, Group:Remote-Groups

Traefik middlewares.yaml

    middlewares-authelia-mydomain:
      forwardAuth:
        address: "http://authelia-mydomain:9091/api/verify?rd=https://authelia.mydomain.com"
        trustForwardHeader: true
        authResponseHeaders:
          - "Remote-User"
          - "Remote-Groups"

Do I need to create a new forwardauth middlewares with

authReponseHeaders: 
   -"HTTP_REMOTE_USER"?

How can I get Remote-User and HTTP_REMOTE_USER working side by side?

There's no documentation on it, so if I can get it working I'll add the instructions to the documentation.

@shamoon
Copy link
Contributor Author

shamoon commented Mar 2, 2021

No, I have it setup basically the same way and its working. You set the PAPERLESS_ENABLE_HTTP_REMOTE_USER env variable to true?

@jonaswinkler
Copy link
Owner

I have no Idea about these things. #677 Will allow customizing the name of the header which paperless will look for if PAPERLESS_ENABLE_HTTP_REMOTE_USER is enabled. Not sure if this helps.

@lenaxia
Copy link

lenaxia commented Mar 2, 2021

Yeah I have it set to true, I'll keep futzing about with it. Shamoon, could you share your config files where relevant? So I can make sure I'm not messing something up?

 36     environment:
 37       - PAPERLESS_REDIS=redis://redis:6379
 38       - PAPERLESS_TIKA_ENABLED=1
 39       - PAPERLESS_TIKA_GOTENBERG_ENDPOINT=http://gotenberg:3000
 40       - PAPERLESS_TIKA_ENDPOINT=http://tika:9998
 41       - PAPERLESS_FILENAME_FORMAT={created_year}/{correspondent}/{title}
 42       - PAPERLESS_ENABLE_HTTP_REMOTE_USER=true
 43       - PUID=${PUID}
 44       - PGID=${PGID}
 45       - TZ=${TZ}  

@shamoon
Copy link
Contributor Author

shamoon commented Mar 2, 2021

Hmm, yea my guess would be somewhere in your authelia/traefik config? Just tested again to make sure Im not crazy 🤪 and its working for me, but yea this stuff is kind of opaque. I use labels not configs but here's the only relevant stuff, I think:

      # Middlewares > rate-limit
      - traefik.http.middlewares.rate-limit.ratelimit.average=100
      - traefik.http.middlewares.rate-limit.ratelimit.burst=50
      # Middlewares > CORS
      - traefik.http.middlewares.corsheaders.headers.accesscontrolalloworiginlist=https://login.mydomain.com [...]
      - traefik.http.middlewares.corsheaders.headers.addvaryheader=true
      # Middlewares > authelia
      - traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://login.mydomain.com/
      - traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true
      - traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups, X-Authenticated-User
      # Middlewares > chains
      - traefik.http.middlewares.chain-authelia.chain.middlewares=rate-limit,corsheaders,authelia
  paperless:
    image: jonaswinkler/paperless-ng:latest
    [...]
      - traefik.http.routers.paperless.middlewares=chain-authelia
    [...]
    environment:
    [...]
      - PAPERLESS_ENABLE_HTTP_REMOTE_USER=true

@lenaxia
Copy link

lenaxia commented Mar 2, 2021

So looks like the X-Authenticated-User was part of the problem. I can get past the normal login page, but when I then click "Documents" I get prompted for basicAuth.

image

Will keep trying.

Edit: There's also some weird behavior around my admin account. Authelia is backed by LDAP for me, but I don't have an admin user. If I login to the admin page with my admin user (paperless only), it keeps kicking me out and I can't complete any actions.

I need to have matching users in paperless right?

Edit2: It looks like if I pass auth from a user in Authelia that doesn't exist in paperless, paperless will auto create the user but with no password (so can't login). Still running into the basic auth issue. Any ideas?

@p-v-a
Copy link

p-v-a commented Jul 29, 2021

I've been trying to configure Paperless with Authelia, the user part works just fine. However I have an issue accessing admin part of the site, as it seems there is no way to assign admin role to an account obtained from SSO.

I have configured Authelia to bypass /admin/* and /static/admin/*, and if I'm not logged in in SSO it works, I can logon into admin site with local admin account. However, if I'm logged in into SSO, this won't work, because SSO still adds headers and Remote-User header takes precedence and I can no longer login with local admin account.

What option do we have to make this works? Ideally Paperless should also respect Remote-Group header, and map it in to local groups. or ignore Remote-User header for admin part of the site? I'll try to remove SSO headers but it will be non-intuitive.

Regards

@shamoon
Copy link
Contributor Author

shamoon commented Jul 31, 2021

@p-v-a If you create the user in paperless cant you assign admin role?

@p-v-a
Copy link

p-v-a commented Jul 31, 2021

@p-v-a If you create the user in paperless cant you assign admin role?

Hi Shamoon,

It works, though it's inconvenient, it's chicken and egg problem. If I configure Authelia, I can no longer login into admin part, or with local credentials. So I have to configure Authelia, login once, disable Authelia, login with local credentials, add Admin role to the user, re-enable Authelia. I know it's one off task, but still.

It would be nice if I can assign group or role based of Remote-Groups.

For now I created conditional forwarding via Authelia, but it's really ugly. I have to configure two ingresses so I can bypass Authelia altogether for admin admin path, because otherwise headers takes priority over local logins, and I can't login into admin part with local admin credential.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants