Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE_REQUEST] Add Header Authentication #981

Open
FieldofClay opened this issue Nov 21, 2022 · 13 comments
Open

[FEATURE_REQUEST] Add Header Authentication #981

FieldofClay opened this issue Nov 21, 2022 · 13 comments
Labels
🦄 Feature Request [ISSUE] Suggestion for new feature, update or change 📌 Keep Open [ISSUE][PR] Prevent auto-closing

Comments

@FieldofClay
Copy link

Is your feature request related to a problem? If so, please describe.

Currently the only authentication options are Keycloak and inbuilt auth. I use Authelia to manage my SSO, which supports passing user/group info through to the reverse proxied app. There are also other apps out there that can pass in user/group info in a similar way.

Describe the solution you'd like

I see this providing the same functionality as the current Keycloak auth, just grabbing the user/group info from headers passed via the proxy instead of interrogating Keycloak.

appConfig.auth (optional)

Field Type Required Description
enableHeaderAuth boolean Optional If set to true enable Header Authentication. See appConfig.auth.headerAuth.

appConfig.auth.headerAuth (optional)

Field Type Required Description
userHeader string Optional Header name which contains username (default: X-Forwarded-User)
groupHeader string Optional Header name which contains group info (default: X-Forwarded-Groups)
proxyWhitelist array Required Upstream proxy servers to expect authenticated requests from.

From here it could use the already existing hideForUsers and showForUsers config, but given that Keycloak has them split out I'm not sure how feasible it is. Could also extend the displayData options to have hideForGroup and showForGroup for extra configurability.

Priority

Medium (Would be very useful)

Is this something you would be keen to implement

No

@FieldofClay FieldofClay added the 🦄 Feature Request [ISSUE] Suggestion for new feature, update or change label Nov 21, 2022
@liss-bot
Copy link
Collaborator

This issue has gone 6 weeks without an update. To keep the ticket open, please indicate that it is still relevant in a comment below. Otherwise it will be closed in 5 working days.

@liss-bot liss-bot added the ⚰️ Stale [ISSUE] [PR] No activity for over 1 month label Dec 22, 2022
@FieldofClay
Copy link
Author

I believe this is still relevant.

@liss-bot liss-bot added 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending and removed ⚰️ Stale [ISSUE] [PR] No activity for over 1 month labels Dec 22, 2022
@Lissy93 Lissy93 added the 📌 Keep Open [ISSUE][PR] Prevent auto-closing label Dec 22, 2022
@liss-bot liss-bot removed the 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending label Dec 23, 2022
@toddejohnson
Copy link
Contributor

I started to try to hack this in as it is just process.env.REMOTE_USER or similar but the client side nature Vuejs and the Axios is a bit more than I can wrap my head around.

@liss-bot liss-bot added the 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending label Nov 16, 2023
toddejohnson added a commit to toddejohnson/dashy that referenced this issue Nov 17, 2023
@toddejohnson
Copy link
Contributor

I found your 2.1.2 and it had a good start at the config race condition in main.js that I was running into with implementing headerAuth. I will say I'm not that good at async coding so there might be some big issues. I have it working for my use case which isn't what a maintainer likes to hear.

  1. It is currently hardcoded for my REMOTE-USER mostly because I don't know how to access getAppConfig().headerAuth.userHeader in the nodejs services/get-user.js which is one of the few things I need to make this configurable.
  2. There is no documentation on how to use this. I'm using Authelia but this would work for Apache/NGINX basic/ldap auth too. Even Apache and mod_auth_mellon(SAML) would allow adding a username header.
  3. I'm using the built in users 'database' to get the hash and fake like a normal user instead of the bolt on that is Keycloak with it's own auth level.

I'll try to work on a WIP PR in a bit.

Lissy93 added a commit that referenced this issue Dec 17, 2023
…onfig

Attempt at adding header auth. Ignore Settings #981
@liss-bot liss-bot removed the 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending label Feb 29, 2024
@toddejohnson
Copy link
Contributor

It looks like this missed 2.1.2. Should I try again? Lots of auth/permissions config could use server side help to limit information leak.

@liss-bot liss-bot added 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending and removed 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending labels Apr 6, 2024
@Lissy93
Copy link
Owner

Lissy93 commented Apr 21, 2024

It looks like this missed 2.1.2. Should I try again? Lots of auth/permissions config could use server side help to limit information leak.

Sorry @toddejohnson, this slipped my mind. I'll look into this this week, and see if we can get something working :)


I started to try to hack this in as it is just process.env.REMOTE_USER or similar but the client side nature Vuejs and the Axios is a bit more than I can wrap my head around.

Yeah, it's annoying. If you need to read an env var client-side, prefix it with VUE_APP_ and then it can be read in Vue.

@rxunique
Copy link

rxunique commented Apr 27, 2024

Edit: Got Authentik proxy working with Dashy 3.0 behind traefik with config below

   users:
      - user: user1
        hash: removed
        type: admin
      - user: user2
        hash: removed
   enableHeaderAuth: true
   headerAuth:
      userHeader: X-Authentik-Username  # the tag containing username according whoami
      proxyWhitelist:
        - "treafik.docker.network.ip"  # 

@liss-bot liss-bot added the 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending label Apr 27, 2024
@rxunique
Copy link

rxunique commented Apr 27, 2024

Edit: found root cause of reload loop

proxyWhitelist has to have traefik docker network ip since my dashy is on the same network

Otherwise response.data.user.toLowerCase() undefined in HeaderAuth.js causing .catch(() => window.location.reload());
to infinite loop

Food for thought @Lissy93

  1. Maybe replace .catch(() => window.location.reload()); at the end of main.js with CoolConsole, at least won't be a reload loop

  2. proxyWhitelist seems to be cached until container restart or there might be some other cache, which made it seem like intermittent issue, maybe add some info to documentation.

  3. perhaps make proxyWhitelist check against "172.16.0.0/12" notation rather than single IP in array?

  4. up on saving to conf.yml via GUI, all previous manual #comment are deleted, it'd be nice if they can be kept

One more thing, Dashy's log out doesn't really work anymore with headerAuth via Authentik proxy. I don't think there is a good solution for this one. As long as signed into Authentik, the username header will always be there

@liss-bot liss-bot removed the 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending label Apr 28, 2024
@Lissy93
Copy link
Owner

Lissy93 commented Apr 28, 2024

@rxunique - You're absolutely correct, shouldn't be triggering a page reload there (not sure why I put that?!). I've updated.

I'm just looking into the header auth feature at the moment, and if I can get something working this evening, will merge as part of 3.0.1. But I'm struggling to understand what exactly needs implementing in Dashy to get this working. I've not really used Authelia, quickly tested it out with NGINX, and it seemed to work alright.

So any tips on what specifically isn't working or what needs to be added/amended would be appreciated :)

@rxunique
Copy link

rxunique commented Apr 28, 2024

Oh pretty much nothing you need to implement, existing code works, documentation would be nice. It was quite head against the wall trying to figure it out, but with benefit of hindsight, it's so obvious.

The flow is like this

  • Authtik proxy auth will add header X-Authentik-Username X-Authentik-Email X-Authentik-Groups
  • In dashy specify auth.users and auth.headerAuth.userHeader=X-Authentik-Username
  • In dashy specify the correct IP

That's it, if authentik username (or alternative fields) matches dashy users, you are in with per user authentication.

The difficulty I ran into, which may be improved on a back burner

  • the page loop which you already fixed
  • proxyWhitelist seems to be cached on container start making testing not that easy, or maybe its something else, wasn't too sure
  • make proxyWhitelist matches IP by range (currently match by string). it will make things a lot easier

In my case, since all behind Traefik on the same docker network, it was my Traefik container ip 172.x.x.x.

Because I restarted different containers while trying to figure it out, their IP changed which made it quite a guess work with proxyWhitelist, now I've got key containers on static ip.

A generic OIDC would be superior than authetik proxy auth + dashy headerauth, but it works now.

@liss-bot liss-bot added the 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending label Apr 28, 2024
@rxunique
Copy link

Hey, just another idea to deal with whitelist.

Currently matching by string is just one line of code, matching by range would need quite a few extra line of code but still need some guess work.

Different people setup docker network and proxy differently, so proxy IP as appeared to dashy will always be different.

What about add another match condition like (proxySecret === X-Dashy-ProxySecret) || proxyWhitelist.includes() , its very easy to manually add a header 'X-Dashy-ProxySecret = MySecretHash' with proxy, certainly with treafik. That way no guess work with

@toddejohnson
Copy link
Contributor

The idea is to list the trusted IP of the reverse proxy that is trusted. If a request from another IP was made saying it was someone else logged in it shouldn't be trusted.

@liss-bot liss-bot removed the 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending label Apr 29, 2024
@Hazzard17h
Copy link

How is the status of this feature?
I see an implementation in #1390, but it doesn't implemented the groupHeader config. Also I don't get why it's selecting users from the auth.users configured ones: if we are behind an auth proxy I guess we can just setup the user from userHeader as the logged one.

@liss-bot liss-bot added 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending and removed 👤 Awaiting Maintainer Response [ISSUE] Response from repo author is pending labels Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🦄 Feature Request [ISSUE] Suggestion for new feature, update or change 📌 Keep Open [ISSUE][PR] Prevent auto-closing
Projects
None yet
Development

No branches or pull requests

6 participants