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

User authentication via reverse proxy request header #165

Closed
qqiao opened this issue May 6, 2014 · 69 comments
Closed

User authentication via reverse proxy request header #165

qqiao opened this issue May 6, 2014 · 69 comments
Assignees
Labels
🎯 feature Categorizes as related to a new feature

Comments

@qqiao
Copy link

qqiao commented May 6, 2014

In some organizations or setups, users are managed separately by systems that does not support oauth.

Usually these setups handle user authentication with an reverse proxy and the user ids are then passed to the downstream systems via a request header.

I happen to work for such an orginazation and with some pointers and guidance, I would like to help implement this feature.

@lunny
Copy link
Contributor

lunny commented May 6, 2014

You are welcome to PR to branch dev.

@unknwon unknwon added the feature label May 6, 2014
@unknwon
Copy link
Member

unknwon commented May 6, 2014

To be honest with you, I'm not fully understanding this feature? Would you please give an example?

@ptman
Copy link
Contributor

ptman commented May 19, 2014

I too would like to be able to integrate to our SSO. I would configure a reverse proxy in front of gogs and add a header to each request from the proxy that specifies the authenticated user. No requests without an authorized user would make it to gogs, as the reverse proxy would block access.

@lunny
Copy link
Contributor

lunny commented May 19, 2014

@ptman Is there any standard for the header? We need retrieve username from the header which has logged in.

@ptman
Copy link
Contributor

ptman commented May 19, 2014

Typically it is configurable. One common way is to interpret only the user part of a HTTP Basic Authentication header. Other systems set a custom header, e.g. X-Authenticated-User

@lunny
Copy link
Contributor

lunny commented May 19, 2014

We could write a http basic authentication middleware on martini to resolve this problem.

@ptman
Copy link
Contributor

ptman commented May 19, 2014

While that would work for e.g. mod_auth_pubtkt with TKTAuthFakeBasicAuth other SSO solutions just set the plain username in a header, e.g. X-WEBAUTH-USER

@unknwon
Copy link
Member

unknwon commented May 19, 2014

Typically it is configurable.

Right.

We could write a http basic authentication middleware on martini to resolve this problem.

Same functions that are used for session can check header first and then check session, which probably isn't much work.

@unknwon unknwon self-assigned this May 19, 2014
@ptman
Copy link
Contributor

ptman commented May 25, 2014

Yes, checking the header before session sounds like a reasonable way to do this.

@unknwon
Copy link
Member

unknwon commented May 25, 2014

Cool, I'll do it.

@compressed
Copy link
Contributor

You can use https://github.com/bitly/google_auth_proxy and set your upstream to the gogs instance. I've been doing this and it's working well.

@ptman
Copy link
Contributor

ptman commented Jun 4, 2014

Maybe it's my reading comprehension, but I couldn't figure out how google_auth_proxy tells upstream which user is authenticated. And gogs still needs to pick that up, otherwise you first need to authenticate to google_auth_proxy and then to gogs...

Update: No wait, it is mentioned that it can pass basic_auth "information", so I guess it sets the basic auth header

@unknwon
Copy link
Member

unknwon commented Jun 4, 2014

Don't worry, this will be implemented in v0.5.0, which is current release period.

@unknwon unknwon added this to the Release v0.5.0 milestone Jun 10, 2014
unknwon added a commit that referenced this issue Jun 21, 2014
@unknwon
Copy link
Member

unknwon commented Jun 21, 2014

Hi there, to use this feature, change following options in config file:

[service]
ENABLE_REVERSE_PROXY_AUTHENTICATION = true

[security]
REVERSE_PROXY_AUTHENTICATION_UID = X-WEBAUTH-UID

Note: the value of X-WEBAUTH-UID is the ID number of user based on Gogs database.

Please try in dev branch code and give us feedback!

@ptman
Copy link
Contributor

ptman commented Jun 24, 2014

Is the header really the uid number of the user? The number in the gogs database? So for a Single Sign On service to be able to authenticate a user it needs to query the user id number of a username from the gogs database in order to be able to set the correct header?

It would make much more sense to set the header to the username, so that the usernames are shared in different systems (like LDAP) and the SSO doesn't have to touch the gogs database.

@unknwon
Copy link
Member

unknwon commented Jun 24, 2014

Right, but the username has to match the user in Gogs database, otherwise Gogs will simply ignore. If we're going this way, then I'll change code to check user name.

@ptman
Copy link
Contributor

ptman commented Jun 24, 2014

Yes, the username has to match. Just as it has to do with LDAP.

unknwon added a commit that referenced this issue Jun 24, 2014
@unknwon
Copy link
Member

unknwon commented Jun 24, 2014

Now changed to:

[service]
ENABLE_REVERSE_PROXY_AUTHENTICATION = true

[security]
REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER

@rojaro
Copy link
Contributor

rojaro commented Jun 25, 2014

Awesome 👍

@ptman
Copy link
Contributor

ptman commented Jul 7, 2014

Sorry it took me so long to reply.

It's working now. I got it to work with mod_auth_pubtkt by basically adding this one line to my apache virtual host config:

RequestHeader set X-WEBAUTH-USER %{REMOTE_USER}e

Would it be possible to autocreate users like with LDAP auth? And maybe fill in the fields from an LDAP auth source?

@unknwon
Copy link
Member

unknwon commented Jul 7, 2014

Would it be possible to autocreate users like with LDAP auth? And maybe fill in the fields from an LDAP auth source?

Yes, we can. I'm thinking of admin give some secret key string(to verify reverse proxy identity) in admin setting panel, and then use another request header like:

RequestHeader set X-WEBAUTH-SECRET <secret key>
RequestHeader set X-WEBAUTH-OP AUTO-CREATE

To tell Gogs create if not exist.

How's this sound?

@ptman
Copy link
Contributor

ptman commented Jul 7, 2014

I could live with that. But I would prefer to set autocreate (and configure the LDAP backend for populating mail and name) in app.ini. I have HTTP_ADDR = 127.0.0.1 and no users allowed to log in on that virtual machine. So the only way to reach gogs is via the proxy. Which means that the proxy can (has to) be trusted.

@unknwon
Copy link
Member

unknwon commented Jul 7, 2014

You mean use LDAP auth or just like the way LDAP works?

@smyrman
Copy link

smyrman commented Dec 8, 2014

PS! I'm only planning private usage of gogs -- so I don't need this to be as perfect/secure as a large company might - just thought I would point it out:-) Having the email set to blank, would also work from a security perspective -- It would require a small schema migration though.

@unknwon
Copy link
Member

unknwon commented Dec 8, 2014

Besides, if the default @gogs.io adresses
really exist, you risk emails being sent random strangers, which could pose
a security threat.

I'v changed this to UUID@localhost so it shouldn't be a problem anymore. Thanks for pointing out though!

My idea is to not create the user before the correct email has been
supplied -- prefer to fetch the email from LDAP, fallback to ask the user
himself what the email is. It's more secure, and less prone to stupid
users, that's all:-)

I'm not quite sure about how reverse proxy auth work flow, so I guess this process could be a paradox in some sense. You can create another issue for discussing this, this one is fairly too old.

Having the email set to blank

Gogs simply does not allow empty e-mail, this affects a lot and I cannot recall all of them at once.

@smyrman
Copy link

smyrman commented Dec 8, 2014

I'v changed this to UUID@localhost

Ah, great. That should be good enough:-)

 You can create another issue for discussing this, this one is fairly

too old.

I guess there is no need. LDAP Sync of email + HTTP proxy auth would be a
nice combo, if it doesn't already work, but I will leave it for somebody
who needs it to raise that ticket.

Otherwise Sorry for spamming such and old ticket -- it was pointed to by
api.ini as a reference:-)

@unknwon
Copy link
Member

unknwon commented Dec 8, 2014

@smyrman sure, no problem.

@ptman
Copy link
Contributor

ptman commented Dec 8, 2014

Retrieving missing information from LDAP would definitely be nice.

@unknwon
Copy link
Member

unknwon commented Mar 12, 2015

!!! Hi, everyone in this thread, please be noticed that by correction of my typo in the configuration(#1038), reverse proxy auto registration key name has been changed !!!

@warpedgeoid
Copy link

As an alternative, could we allow the reverse proxy to pass additional LDAP information as headers? Presumably, if the RP is authenticating users, it has access to the LDAP/AD tree and can pass X-User-Email, X-User-Name, etc. Why should Googs need access to the LDAP in this situation? Someone correct me if I'm wrong.

@unknwon
Copy link
Member

unknwon commented Dec 8, 2015

@warpedgeoid I'm not sure if I understand correctly, but only UID is unique and never can be changed in Gogs, this is the safest way.

@ptman
Copy link
Contributor

ptman commented Dec 8, 2015

@unknwon The UID in gogs is internal to gogs. No LDAP server knows the UID values in gogs database. Users must be identified by username, or something that can be known by the LDAP database for this to work. Maybe LDAP users should be prevented from changing their name in gogs.

@unknwon
Copy link
Member

unknwon commented Dec 8, 2015

@ptman ahah, sorry, forgot it was passing the user name, but yes same thing apply. And As I said i'm not quite get the point of @warpedgeoid 's comment...

@warpedgeoid
Copy link

My point was more that instead of querying LDAP to get certain user profile information (like is being requested above to compliment ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = true), why not just allow the reverse proxy to pass these in the same manner as the username? Sure, this isn't as robust as querying LDAP, but it is much easier to implement. After all--we are only talking about the user's full name, email address and profile picture.

@unknwon
Copy link
Member

unknwon commented Dec 9, 2015

My point was more that instead of querying LDAP to get certain user profile information (like is being requested above to compliment ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = true), why not just allow the reverse proxy to pass these in the same manner as the username? Sure, this isn't as robust as querying LDAP, but it is much easier to implement. After all--we are only talking about the user's full name, email address and profile picture.

Of course there is no technical difficulties on implementing this, but what is the use case?

@warpedgeoid
Copy link

The use case, as I see it, is as a simple method of doing what @smyrman wants to do with this pseudo-code, but without having to add an LDAP layer to reverse proxy auth. It would just look for the email address as an extra header, just like it currently does the username.

If reverse proxy enabled and reverse proxy username set in header:
     If user exists:
          log in user
          return
    If ldap configured:
        email, error = get email from ldap.
        if error == nil:
            set user email
            return
    show a custom "register proxy user" form where the username (and password) can not be changed, but email must be provided.

@unknwon
Copy link
Member

unknwon commented Dec 10, 2015

@warpedgeoid thanks, but what you give is implementation, not use case...

And @smyrman 's comment is really old, please give explicit reference to words you're referencing to, not xxx wants.

@bonitoDeMadrid
Copy link

Love that feature.
Is it possible to get this working with the git client, too?

Scenario:
git client => reverse proxy over https (doing authentication via client certificates) => gogs

Expected:
git init 
' git is already configured to use the client certificate for that domain...
git remote add origin https://gogs.mycomany.com 
git fetch
' It work's withouth asking for user credentials

Since users love to forget passwords in bigger companys, ....
Funny: There was a press release in germany this week, that VW spend
a million bugs a year for resetting user passwords, btw.

@unknwon
Copy link
Member

unknwon commented Dec 13, 2015

@bonitoDeMadrid very interesting point!

Would you mind rise another issue specifically for git HTTP?

@donbowman
Copy link
Contributor

@unknwon above you say the default password is same as username (for auto created user via ENABLE_REVERSE_PROXY_AUTO_REGISTRATION for operations such as delete-repo).
But I am finding I cannot delete a repo specifying the user name as the password.
I do see the code sets it:
069486d
but it doesn't seem to work. Do others see this?

@unknwon
Copy link
Member

unknwon commented Jan 7, 2016

@donbowman based on the code it should work. Do you have any other info you may consider helpful to debug this issue?

@Kegeruneku
Copy link

Greetings @unknwon !

I would also be interested in having a way to have a way to fill basic info about the user auto-created by ENABLE_REVERSE_PROXY_AUTO_REGISTERATION.

As said by previous commenters, it could either be passed using http headers, or if available using a configured LDAP provider (this is what others application usually do when applicable)

The use case is simple: I would love to at least have the correct mail for the user so he/she does not have to redefine profile info after initial login. (it is needed for mails to be sent in case of updates and having to redefine it is tedious especially when the info is actually already available somewhere)

The user first name / last name would be a bonus (if possible, but the mail is more important)

I'll be around if you need precisions :)

@unknwon
Copy link
Member

unknwon commented Jan 27, 2016

@Kegeruneku thanks your info!

I suggest you open up another issue with same comment you posted, and name it Fill basic info when auto-created user by reverse proxy.

@Kegeruneku
Copy link

Can do! And thanks for that awesome software btw :-)

@mcanevet
Copy link

Has anyone managed to make this work with https://github.com/bitly/oauth2_proxy?

@msiebuhr
Copy link

msiebuhr commented May 9, 2016

@mcanevet

Adding this to app.ini:

[security]
INSTALL_LOCK = true
SECRET_KEY   = ...
REVERSE_PROXY_AUTHENTICATION_USER = X-Forwarded-User

[service]
ENABLE_REVERSE_PROXY_AUTHENTICATION = true
ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = true

After starting the server on http://localhost:3000, I start up oauth2_proxy with:

oauth2_proxy --upstream=http://localhost:3000 --client-id=`cat client_id.txt` --client-secret=`cat client_secret.txt` --cookie-secret=... --email-domain=\* --cookie-secure=false

(Yes, secrets should at least be passed in environment vars or a config file.)

@belongwqz
Copy link

When I user nginx to enable reverse proxy auth for sso, git clone (cmd is git clone http://xxxxx.git) always return http 5xx error, what I should do please ?

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 26, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🎯 feature Categorizes as related to a new feature
Projects
None yet
Development

No branches or pull requests