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

[feat] Add X-Remote-User header #135

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

MistaTwista
Copy link

In some cases there are needs to Authorize user not in Taskcafe itself.
For this reason option server.remote_user_header was added.

[server]
remote_user_header = true

With turned on Taskcafe listens X-Remote-User http header and skip
password checking. But still check user existence and active flag.

  • Please check if the PR fulfills these requirements
  • You have read the contribution guidelines guidelines
  • The commit message follows our guidelines
  • Docs have been added / updated (for bug fixes / features)
  • What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
    This was in discussion Feature: Authenticate via "Remote User" header #49

  • What is the current behavior? (You can also link to an open issue here)
    Check user and password at login handler. Add token in DB. Return cookie.

  • What is the new behavior (if this is a feature change)?
    Add an option server.remote_user_header (bool). Default is false.
    If it's true – taskcafe will not check user password, but still find it in DB and check it's activeness.

  • Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)
    no

  • Other information:


func (h *TaskcafeHandler) xHeaderAuthenticate(w http.ResponseWriter, r *http.Request) {
xRemoteUser := r.Header.Get("X-Remote-User")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth making this configurable from the start- my proxy actually passes Remote-User (no X-), and I've seen examples implying several other names for this header. Does Go have an optional string type? that could work instead of a boolean for server_remote_user_header, with absence indicating "feature is turned off".

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeap, was thinking about it already :)

In some cases there are needs to authenticate user not in Taskcafe itself.
For this reason option server.remote_user_header was added.

```toml
[server]
remote_user_header = "X-Remote-User"
```

With turned on Taskcafe listens X-Remote-User http header and skip
password checking. But still check user existence and activity flag.
@@ -139,9 +148,47 @@ func (h *TaskcafeHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
authCreatedAt := time.Now().UTC()
authExpiresAt := authCreatedAt.AddDate(0, 0, 1)
authToken, err := h.repo.CreateAuthToken(r.Context(), db.CreateAuthTokenParams{user.UserID, authCreatedAt, authExpiresAt})
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
// TODO: should we return here?
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JordanKnott is this a feature?

Copy link
Owner

@JordanKnott JordanKnott Oct 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're talking about not returning early on an error, it is not

@JordanKnott
Copy link
Owner

JordanKnott commented Oct 21, 2021

Based on the discussions in #49, we should have the remote user header be accepted in place of the current access cookie rather than implementing a separate authentication path in /auth/login.

This way the authentication flow would be

User requests index.html -> Proxy handles authentication -> index.html loads -> `<Remote User Header>` is accepted in place of regular access cookie so user is immediately logged in.

So the changes would likely mostly be in the authentication middleware.

However, one problem with going this route would be that public routes would no longer be public since the proxy would require authentication.

I am also a little hesitant on adding features without some platform that I can actually test the implementation. @aroberts - what proxy setup were you planning on using with this added feature? Perhaps I can setup something similar for testing.

@aroberts
Copy link

I'll be using this with Authelia. There's a "getting started" compose file with documentation about defining users statically via file, rather than having to set up ldap. I'm not intending this service to be usable by anyone not logged in, but if I did, Authelia lets me scope the auth challenge to only specific path prefixes. I think that's a fairly common pattern (auth on specific prefixes only) in this space, due to this exact problem.

@aroberts
Copy link

aroberts commented Nov 5, 2021

@JordanKnott do you see a path forward for this? I don’t think the public routes are an issue- if I wanted them to remain public, I’d just configure my authentication proxy not to apply the auth challenge to those routes. This is a feature of virtually every tool that sits in this role (auth proxy) because of exactly the problem you point out.

@JordanKnott
Copy link
Owner

I think the way forward would be to change the authentication logic to what I described in the my last comment - and leave handling the public routes up to the user (like you described).

@aroberts
Copy link

aroberts commented Nov 2, 2022

Any luck here? I'd love to see this feature make it in.

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

Successfully merging this pull request may close these issues.

3 participants