Google authentication for Gerrit and Jenkins
Asked Answered
D

3

16

Jenkins and Gerrit have both plugins for OpenID 2.0, but this API has been deprecated by Google May 19 2014 (https://developers.google.com/accounts/docs/OpenID) making it impossible for new installation to use and existing installations must migrate to OAuth2.0(OpendID connect). When trying to use OpenID 2.0 you will get the error message "Error 400: OpenID auth request contains an unregistered domain".

The Gerrit team is aware of the problem but no solution as of yet: https://code.google.com/p/gerrit/issues/detail?id=2677

Not sure about Jenkins.

Delete answered 6/10, 2014 at 11:37 Comment(1)
To fit the expectations of a Q&A site, there should be a question here. Perhaps that would have helped me understand what your answer contained.Basswood
D
12

Update 2014/11/05: For those coming here the first place read on below. Thanks hans-zandbelt for the feedback. It is incorporated in the updated version. The setup now uses the suggested improvements and only uses mod_rewrite to redirect the gerrit logout url to the right place. Also note that instead of only using the non-domain part of the email the email is used unmodified. This means that if you happen to have an existing setup you need to change username mappings.

For Jenkins do the following:

  • move ${jenkins_home}/users/youruser to ${jenkins_home}/users/youruser@yourdomain
  • open ${jenkins_home}/config.xml search "youruser" and replace with youruser@yourdomain

For Gerrit:

either on the machine itself (change GERRIT_HOME to where it is on your machine):

  • open the sql database with one of the two methods below:

    1. [Recommended] Either through the gerrit command available through ssh:

      ssh  gerrit.revault.ch gerrit  gsql
      
    2. OR on the machine itself (change GERRIT_HOME to where it is on your machine):

      export GERRIT_HOME=/var/gerrit_home
      pushd ${GERRIT_HOME}
      java -cp $(find . -name "h2*.jar") org.h2.tools.Shell -url "jdbc:h2:file:${GERRIT_HOME}/db/ReviewDB;IFEXISTS=TRUE"
      
  • show external

    select * from ACCOUNT_EXTERNAL_IDS;
    
  • the external ids map your account to different usernames, emails etc.

  • the ones prefixed with username: e.g. username:[email protected] are for ssh / git login names
  • the ones prefixed with gerrit: e.g. gerrit:[email protected] are used for the web interface
  • for a given account_id you can just add new mappings for existing users using sql: e.g.

    insert into ACCOUNT_EXTERNAL_IDS values(1000032, NULL,NULL, 'username:[email protected]');
    insert into ACCOUNT_EXTERNAL_IDS values(1000032, NULL,NULL, 'gerrit:[email protected]');
    


Solution

You can use an Apache as a reverse proxy handling authentication for you:

Gerrit

Assuming you already have installed Gerrit and it is listening on address 10.10.10.10:8080. You will have to configure gerrit to use basic authentication, the [auth] section in your ${gerrit_installation}/etc/gerrit.config should look like this:

[gerrit]
        basePath = git
        canonicalWebUrl = http://gerrit.example.com
[database]
        type = h2
        database = db/ReviewDB
[index]
        type = LUCENE
[auth]
        type = HTTP
        emailFormat = {0}@example.com
        httpHeader =  X-Forwarded-User
[sendemail]
        smtpServer = localhost
[container]
        user = gerrit
        javaHome = /usr/lib/jvm/java-8-oracle/jre
[sshd]
        listenAddress = 10.10.10.10:2222
[httpd]
        listenUrl = http://10.10.10.10:8080/
[cache]
        directory = cache

The username will be in the header X-Forwarded-User. That's how Apache will forward the username to Gerrit.

On Apache we will use mod_auth_openidc which has support for oauth2. For further information and example docs refer to https://github.com/pingidentity/mod_auth_openidc. On a recent Ubuntu the installation looks like this:

sudo aptitude install libjansson-dev apache2 apache2-dev libcurl4-openssl-dev build-essential autoconf libhiredis-dev

git clone https://github.com/pingidentity/mod_auth_openidc.git
cd mod_auth_openidc
./autogen.sh 
./configure
make
sudo make install

sudo a2enmod auth_openidc
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod headers
sudo a2enmod rewrite

You will need to add a site configuration e.g. gerrit.conf similar to the one below (you probably want TLS, too) to /etc/apache2/sites-available and activate it with:

sudo a2ensite gerrit.conf

The file /etc/apache2/sites-available/gerrit.conf looks like this:

<VirtualHost *:80>
ServerName gerrit.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

OIDCProviderMetadataURL https://accounts.google.com/.well-known/openid-configuration
OIDCClientID <from api console>
OIDCClientSecret <from api console>

OIDCScope "openid email profile"
OIDCRedirectURI http://gerrit.example.com/oauth2callback
OIDCCryptoPassphrase <generate long random passphrase here, no sure if used>

OIDCSessionInactivityTimeout 600

OIDCCookiePath /

OIDCAuthRequestParams hd=example.com
OIDCRemoteUserClaim email
OIDCAuthNHeader X-Forwarded-User

RewriteEngine On
#LogLevel alert rewrite:trace2
RewriteRule ^/logout$ /oauth2callback?logout=http://gerrit.example.com/ [R]

ProxyPass /  http://gerrit.example.com:8080/ nocanon
ProxyPassReverse / http://gerrit.example.com:8080/
ProxyRequests     Off
AllowEncodedSlashes NoDecode


<Proxy http://gerrit.example.com:8080/*>
# add rewrites here if necessary
</Proxy>

<Location />
   AuthType openid-connect
   Require claim hd:example.com
   Require valid-user
</Location>

</VirtualHost>

In order to get the parameters OIDCClientID and OIDCClientSecret go to the api console under https://console.developers.google.com/project. The credentials are in the context of a project if you haven't one create a project first. E.g. example-it-authentication

Developer Console projects

On the project go to APIs & auth:

  • Under APIs activate Google+ API. Developer Console enabled APIs
  • Under Credentials, OAuth create new Client ID. Developer Console create credentials
  • Fill in OIDCClientID and OIDCClientSecret in your apache config (e.g. gerrit.conf) Developer Console credentials
  • Under Consent screen fill in email and product name (you will get an error if you don't)

service apache2 restart

You should be done!

Jenkins

Assuming you already have installed Jenkins and it is listening on 10.10.10.11:8080.

For Jenkins the configuration is almost identical. You will need to install and activate the Reverse Proxy Auth Plugin http://wiki.jenkins-ci.org/display/JENKINS/Reverse+Proxy+Auth+Plugin. Under Configure Global Security check the "HTTP Header by reverse proxy" radio. Jenkins activating security

The default values correspond to the configuration below. You will need to create credentials matching the jenkins hostname in the api console https://console.developers.google.com/project. Report them to your config as before (e.g. jenkins.conf). That should be all.

<VirtualHost *:80>
ServerName jenkins.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

OIDCProviderMetadataURL https://accounts.google.com/.well-known/openid-configuration
OIDCClientID <from api console>
OIDCClientSecret <from api console>

OIDCScope "openid email profile"
OIDCRedirectURI http://jenkins.example.com/oauth2callback
OIDCCryptoPassphrase <generate long random passphrase here, no sure if used>

OIDCSessionInactivityTimeout 600

OIDCCookiePath /

OIDCAuthRequestParams hd=example.com
OIDCRemoteUserClaim email
OIDCAuthNHeader X-Forwarded-User

ProxyPass /  http://jenkins.example.com:8080/ nocanon
ProxyPassReverse / http://jenkins.example.com:8080/
ProxyRequests     Off
AllowEncodedSlashes NoDecode

<Proxy http://jenkins.example.com:8080/*>
# add rewrites here if necessary
</Proxy>

<Location />
   AuthType openid-connect
   Require claim hd:example.com
   Require valid-user
</Location>

<Location ~ "^/(cli|jnlpJars|subversion|whoAmI|computer/[^/]+/slave-agent.jnlp|tcpSlaveAgentListener)">
 Satisfy Any
 Allow from all 
</Location>

</VirtualHost>

Currently there doesn't seem to be support for groups in mod_auth_openidc. If you need groups you can install an LDAP that stores them (but this probably isn't what you want since you are using Google auth) or wait until it is supported by mod_auth_openidc.

Delete answered 6/10, 2014 at 11:37 Comment(9)
I'm not sure what aspect of the problem is being solved here. Apache can do the new-style authentication, so Gerrit is being told to ask it, rather than Google, for details?Basswood
If you do a new install of Gerrit (new domain), you won't be able to authenticate with Google using the built-in OpenID plugin. Google has deprecated that API and won't let you register new domains. This article shows a workaround until Gerrit supports OAuth2.0 (OpenID connect) out of the box.Delete
Fantastic answer, thank you. I have a question though about the settings in jenkins. If i have a domain admin.olly.com and putting the oauth around the entire domain so that admin.olly.com/jenkins is not accessible without it, do I still need to do the Jenkins security setup? What additional is this adding? Thanks!Jin
Assuming you want to map /jenkins to Jenkins only and have all other dirs served by Apache directly you would just map /jenkins in the ProxyPass/ProxyPassReverse and <Proxy></Proxy> in your Apache conf. The jenkins setup remains the same. Except if you want to use jenkins without distinguishing different users in that case you can just uncheck "Enable security" in Jenkins.Delete
Great answer, but I cant seem to get into the H2 database with option 1 or 2. It states the following: Unrecognized option: -urlSeasonal
I would recommend the SSH method, sorry not having said so. If you must use the shell: In your case it doesn't find the h2*.jar so the command is running with an empty -cp argument. Like this 'java -cp bla -url bla'. Is GERRIT_HOME set to properly? If you run find ${GERRIT_HOME} -name "h2*.jar" on it's own it should find the h2*.jar. Maybe on your installation it lives outside of ${GERRIT_HOME}.Delete
Thanks for your reply. If I try the SSH alternative, it just states 'bash gerrit command not found', so I guess it is not set up properly. Should the 'gerrit' command be aliased to the 'gerrit.sh' in bin? As for the other alternative, my GERRIT_HOME is set to the gerrit folder containing the bin, db, logs, etc (etc..) folders - so it should be correct, however I cannot find h2*.jar - but I got an ReviewDB.h2.db in the db folder. Also I am running version 2.9.1 of gerrit.Seasonal
I am also in the same boat as JAM. This solution doesn't seem to work for me either, more clarification would be greatly appreciated.Halmstad
This solution worked for me when I migrated from google's oauth to openid connect, but I discovered new users can access the UI. Gerrit log was complaining about invalid user names (the email address contained the @ character which gerrit does not accept): Cannot assign user name [email protected] to account 73; name does not conform. The solution was to set OIDCRemoteUserClaim email ^(.*)@ in apache config. The second part of the value is a regex that only returns the name part of the email. After that I had to create new entries in the account_external_ids for existing users without domain.Frippery
R
4

Google's OpenID 2.0 has been superseded by OpenID Connect. The Apache module mod_auth_openidc implements OpenID Connect so it can be used in a reverse proxy that fronts Gerrit/Jenkins as described by revau.lt.

However, be aware that relying on the non-domain part of an e-mail address as a unique identifier is insecure unless you restrict logins to a specific domain using the following two configuration settings:

OIDCAuthRequestParams hd=example.com

to skip Google's account chooser screen, and in the <Location> section:

Require claim hd:example.com

to restrict access to only users from the example.com Google domain. If your application is open to any Google account you should not use the e-mail prefix as the primary identifier because you run the collision risk that users in different domains have the same user prefix.

That is why it is better to rely on the full e-mail address, e.g.

OIDCRemoteUserClaim email

or the (opaque) primary identifier that Google uses in the sub claim, e.g.:

OIDCRemoteUserClaim sub

Furthermore, instead of rewriting claims in to headers you can just use:

OIDCAuthNHeader X-Forwarded-User

Migration from OpenID 2.0 to OpenID Connect (retaining OpenID 2.0 user identifiers) is possible to, as described here and here, so you'd use:

OIDCAuthRequestParams openid.realm=<urlencoded-realm-value>
OIDCRemoteUserClaim openid_id

For an exhaustive overview of configuration primitives see: https://github.com/pingidentity/mod_auth_openidc/blob/master/auth_openidc.conf

Raspings answered 4/11, 2014 at 11:14 Comment(3)
Thank you very much for this. I guess I didn't dig deep enough into the doc. Your suggestions are incorporated in my answer.Delete
you setup seems to use only users from a single domain, in which case I'd strongly advise to use the OIDCRequestParams and Require claim settings as suggested for security reasonsRaspings
your setup assumes that the Google e-mail prefix is actually the same as the username in Jenkins, which is something that needs to be enforced when creating user accounts in Google, people need to be aware of that; another approach to the mapping would be to rewrite the OIDCAuthNHeader after it has been set by mod_auth_openidc, instead of translating all user identifiers in the databaseRaspings
M
2

As I know the fastest way to login into Gerrit with Google account is:

  1. Create Client ID in Google Developers Console
  2. Download this release of Gerrit and Google-OAuth-provider plugin
  3. Re-initialize Gerrit: java -jar gerrit-2.10.1-4-a83387b.war init -d gerrit_site_path
  4. And restart it: gerrit_site_path/bin/gerrit.sh restart

To Jenkins is new Google-login plug-in.

Myongmyopia answered 10/4, 2015 at 8:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.