diff --git a/README.md b/README.md index 7e1b36ca..adead22f 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ - [SAML](#saml) - [Crowd](#crowd) - [Microsoft Azure](#microsoft-azure) + - [Generic OAuth2](#Generic-OAuth2) - [Gitlab Pages](#gitlab-pages) - [External Issue Trackers](#external-issue-trackers) - [Host UID / GID Mapping](#host-uid--gid-mapping) @@ -671,6 +672,14 @@ Once you have the Client ID, Client secret and Tenant ID generated, configure th For example, if your Client ID is `xxx`, the Client secret is `yyy` and the Tenant ID is `zzz`, then adding `--env 'OAUTH_AZURE_API_KEY=xxx' --env 'OAUTH_AZURE_API_SECRET=yyy' --env 'OAUTH_AZURE_TENANT_ID=zzz'` to the docker run command enables support for Microsoft Azure OAuth. +#### Generic OAuth2 + +To enable the Generic OAuth2 provider, you must register your application with your provider. You also need to confirm OAuth2 provider app's ID and secret, the client options and the user's response structure. + +As an example this code has been tested with Keycloak, with the following variables: `OAUTH2_GENERIC_APP_ID`, `OAUTH2_GENERIC_APP_SECRET`, `OAUTH2_GENERIC_CLIENT_SITE`, `OAUTH2_GENERIC_CLIENT_USER_INFO_URL`, `OAUTH2_GENERIC_CLIENT_AUTHORIZE_URL`, `OAUTH2_GENERIC_CLIENT_TOKEN_URL`, `OAUTH2_GENERIC_CLIENT_END_SESSION_ENDPOINT`, `OAUTH2_GENERIC_ID_PATH`, `OAUTH2_GENERIC_USER_UID`, `OAUTH2_GENERIC_USER_NAME`, `OAUTH2_GENERIC_USER_EMAIL`, `OAUTH2_GENERIC_NAME`, + +See [GitLab documentation](https://docs.gitlab.com/ee/integration/oauth2_generic.html#sign-into-gitlab-with-almost-any-oauth2-provider) and [Omniauth-oauth2-generic documentation](https://gitlab.com/satorix/omniauth-oauth2-generic) for more details. + ### Gitlab Pages Gitlab Pages allows a user to host static websites from a project. Gitlab pages can be enabled with setting the envrionment variable `GITLAB_PAGES_ENABLED` to `true`. @@ -1038,6 +1047,18 @@ Below is the complete list of available options that can be used to customize yo | `OAUTH_AZURE_API_KEY` | Azure Client ID. No defaults. | | `OAUTH_AZURE_API_SECRET` | Azure Client secret. No defaults. | | `OAUTH_AZURE_TENANT_ID` | Azure Tenant ID. No defaults. | +| `OAUTH2_GENERIC_APP_ID` | Your OAuth2 App ID. No defaults. | +| `OAUTH2_GENERIC_APP_SECRET` | Your OAuth2 App Secret. No defaults. | +| `OAUTH2_GENERIC_CLIENT_SITE` | The OAuth2 generic client site. No defaults | +| `OAUTH2_GENERIC_CLIENT_USER_INFO_URL` | The OAuth2 generic client user info url. No defaults | +| `OAUTH2_GENERIC_CLIENT_AUTHORIZE_URL` | The OAuth2 generic client authorize url. No defaults | +| `OAUTH2_GENERIC_CLIENT_TOKEN_URL` | The OAuth2 generic client token url. No defaults| +| `OAUTH2_GENERIC_CLIENT_END_SESSION_ENDPOINT` | The OAuth2 generic client end session endpoint. No defaults | +| `OAUTH2_GENERIC_ID_PATH` | The OAuth2 generic id path. No defaults | +| `OAUTH2_GENERIC_USER_UID` | The OAuth2 generic user id path. No defaults | +| `OAUTH2_GENERIC_USER_NAME` | The OAuth2 generic user name. No defaults | +| `OAUTH2_GENERIC_USER_EMAIL` | The OAuth2 generic user email. No defaults | +| `OAUTH2_GENERIC_NAME` | The name of your OAuth2 provider. No defaults | | `GITLAB_GRAVATAR_ENABLED` | Enables gravatar integration. Defaults to `true`. | | `GITLAB_GRAVATAR_HTTP_URL` | Sets a custom gravatar url. Defaults to `http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon`. This can be used for [Libravatar integration](http://doc.gitlab.com/ce/customization/libravatar.html). | | `GITLAB_GRAVATAR_HTTPS_URL` | Same as above, but for https. Defaults to `https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon`. | diff --git a/assets/runtime/config/gitlabhq/gitlab.yml b/assets/runtime/config/gitlabhq/gitlab.yml index e43c58db..c0dc782e 100644 --- a/assets/runtime/config/gitlabhq/gitlab.yml +++ b/assets/runtime/config/gitlabhq/gitlab.yml @@ -571,6 +571,27 @@ production: &base client_secret: '{{OAUTH_AUTH0_CLIENT_SECRET}}', domain: '{{OAUTH_AUTH0_DOMAIN}}', scope: '{{OAUTH_AUTH0_SCOPE}}' } } + - { name: 'oauth2_generic', + app_id: '{{OAUTH2_GENERIC_APP_ID}}', + app_secret: '{{OAUTH2_GENERIC_APP_SECRET}}', + args: { + client_options: { + site: '{{OAUTH2_GENERIC_CLIENT_SITE}}', + user_info_url: '{{OAUTH2_GENERIC_CLIENT_USER_INFO_URL}}', + authorize_url: '{{OAUTH2_GENERIC_CLIENT_AUTHORIZE_URL}}', + token_url: '{{OAUTH2_GENERIC_CLIENT_TOKEN_URL}}', + end_session_endpoint: '{{OAUTH2_GENERIC_CLIENT_END_SESSION_ENDPOINT}}', + }, + user_response_structure: { + id_path: '{{OAUTH2_GENERIC_ID_PATH}}', + attributes: { + uid: '{{OAUTH2_GENERIC_USER_UID}}', + name: '{{OAUTH2_GENERIC_USER_NAME}}', + email: '{{OAUTH2_GENERIC_USER_EMAIL}}' + } + }, + name: '{{OAUTH2_GENERIC_NAME}}' + }} - { name: 'azure_oauth2', args: { client_id: '{{OAUTH_AZURE_API_KEY}}', diff --git a/assets/runtime/env-defaults b/assets/runtime/env-defaults index 38a78608..4dcd3976 100644 --- a/assets/runtime/env-defaults +++ b/assets/runtime/env-defaults @@ -432,6 +432,20 @@ OAUTH_CAS3_LOGOUT_URL=${OAUTH_CAS3_LOGOUT_URL:-/cas/logout} ### AUTH0 OAUTH_AUTH0_SCOPE=${OAUTH_AUTH0_SCOPE:-openid profile email} +## OAUTH2 GENERIC +OAUTH2_GENERIC_APP_ID=${OAUTH2_GENERIC_APP_ID:-} +OAUTH2_GENERIC_APP_SECRET=${OAUTH2_GENERIC_APP_SECRET:-} +OAUTH2_GENERIC_CLIENT_SITE=${OAUTH2_GENERIC_CLIENT_SITE:-} +OAUTH2_GENERIC_CLIENT_USER_INFO_URL=${OAUTH2_GENERIC_CLIENT_USER_INFO_URL:-} +OAUTH2_GENERIC_CLIENT_AUTHORIZE_URL=${OAUTH2_GENERIC_CLIENT_AUTHORIZE_URL:-} +OAUTH2_GENERIC_CLIENT_TOKEN_URL=${OAUTH2_GENERIC_CLIENT_TOKEN_URL:-} +OAUTH2_GENERIC_CLIENT_END_SESSION_ENDPOINT=${OAUTH2_GENERIC_CLIENT_END_SESSION_ENDPOINT:-} +OAUTH2_GENERIC_ID_PATH=${OAUTH2_GENERIC_ID_PATH:-} +OAUTH2_GENERIC_USER_UID=${OAUTH2_GENERIC_USER_UID:-} +OAUTH2_GENERIC_USER_NAME=${OAUTH2_GENERIC_USER_NAME:-} +OAUTH2_GENERIC_USER_EMAIL=${OAUTH2_GENERIC_USER_EMAIL:-} +OAUTH2_GENERIC_NAME=${OAUTH2_GENERIC_NAME:-} + ## ANALYTICS ### GOOGLE diff --git a/assets/runtime/functions b/assets/runtime/functions index 573b9892..eb37c457 100644 --- a/assets/runtime/functions +++ b/assets/runtime/functions @@ -595,6 +595,27 @@ gitlab_configure_oauth_saml() { fi } +gitlab_configure_oauth2_generic() { + if [[ -n ${OAUTH2_GENERIC_APP_ID} && \ + -n ${OAUTH2_GENERIC_APP_SECRET} ]]; then + echo "Configuring gitlab::oauth::generic..." + OAUTH_ENABLED=${OAUTH_ENABLED:-true} + update_template ${GITLAB_CONFIG} \ + OAUTH2_GENERIC_APP_ID \ + OAUTH2_GENERIC_APP_SECRET \ + OAUTH2_GENERIC_CLIENT_SITE \ + OAUTH2_GENERIC_CLIENT_USER_INFO_URL \ + OAUTH2_GENERIC_CLIENT_AUTHORIZE_URL \ + OAUTH2_GENERIC_CLIENT_TOKEN_URL \ + OAUTH2_GENERIC_CLIENT_END_SESSION_ENDPOINT \ + OAUTH2_GENERIC_ID_PATH \ + OAUTH2_GENERIC_USER_UID \ + OAUTH2_GENERIC_USER_NAME \ + OAUTH2_GENERIC_USER_EMAIL \ + OAUTH2_GENERIC_NAME + fi +} + gitlab_configure_oauth_crowd() { if [[ -n ${OAUTH_CROWD_SERVER_URL} && \ -n ${OAUTH_CROWD_APP_NAME} && \ @@ -654,6 +675,7 @@ gitlab_configure_oauth() { gitlab_configure_oauth_gitlab gitlab_configure_oauth_bitbucket gitlab_configure_oauth_saml + gitlab_configure_oauth2_generic gitlab_configure_oauth_crowd gitlab_configure_oauth_auth0 gitlab_configure_oauth_azure @@ -668,7 +690,7 @@ gitlab_configure_oauth() { OAUTH_EXTERNAL_PROVIDERS case ${OAUTH_AUTO_SIGN_IN_WITH_PROVIDER} in - cas3|google_oauth2|facebook|twitter|github|gitlab|bitbucket|saml|crowd|azure_oauth2) + cas3|google_oauth2|facebook|twitter|github|gitlab|bitbucket|saml|crowd|azure_oauth2|oauth2_generic) update_template ${GITLAB_CONFIG} OAUTH_AUTO_SIGN_IN_WITH_PROVIDER ;; *) diff --git a/contrib/docker-swarm/docker-compose.yml b/contrib/docker-swarm/docker-compose.yml index 78fc4327..3e83e326 100644 --- a/contrib/docker-swarm/docker-compose.yml +++ b/contrib/docker-swarm/docker-compose.yml @@ -151,6 +151,19 @@ services: - OAUTH_AUTH0_DOMAIN= - OAUTH_AUTH0_SCOPE= + - OAUTH2_GENERIC_APP_ID= + - OAUTH2_GENERIC_APP_SECRET= + - OAUTH2_GENERIC_CLIENT_SITE= + - OAUTH2_GENERIC_CLIENT_USER_INFO_URL= + - OAUTH2_GENERIC_CLIENT_AUTHORIZE_URL= + - OAUTH2_GENERIC_CLIENT_TOKEN_URL= + - OAUTH2_GENERIC_CLIENT_END_SESSION_ENDPOINT= + - OAUTH2_GENERIC_ID_PATH= + - OAUTH2_GENERIC_USER_UID= + - OAUTH2_GENERIC_USER_NAME= + - OAUTH2_GENERIC_USER_EMAIL= + - OAUTH2_GENERIC_NAME= + - OAUTH_AZURE_API_KEY= - OAUTH_AZURE_API_SECRET= - OAUTH_AZURE_TENANT_ID= diff --git a/docs/docker-compose-keycloak.yml b/docs/docker-compose-keycloak.yml new file mode 100644 index 00000000..54031cdc --- /dev/null +++ b/docs/docker-compose-keycloak.yml @@ -0,0 +1,180 @@ +version: '2' + +services: + redis: + restart: always + image: sameersbn/redis:4.0.9-2 + command: + - --loglevel warning + volumes: + - redis-data:/var/lib/redis:Z + + postgresql: + restart: always + image: sameersbn/postgresql:10-2 + volumes: + - postgresql-data:/var/lib/postgresql:Z + environment: + - DB_USER=gitlab + - DB_PASS=password + - DB_NAME=gitlabhq_production + - DB_EXTENSION=pg_trgm + + gitlab: + restart: always + image: nuberabe/docker-gitlab:12.7.0 + depends_on: + - redis + - postgresql + ports: + - "10080:80" + - "10022:22" + volumes: + - gitlab-data:/home/git/data:Z + environment: + - DEBUG=false + + - DB_ADAPTER=postgresql + - DB_HOST=postgresql + - DB_PORT=5432 + - DB_USER=gitlab + - DB_PASS=password + - DB_NAME=gitlabhq_production + + - REDIS_HOST=redis + - REDIS_PORT=6379 + + - TZ=Asia/Kolkata + - GITLAB_TIMEZONE=Kolkata + + - GITLAB_HTTPS=false + - SSL_SELF_SIGNED=false + + - GITLAB_HOST='' + - GITLAB_PORT=10080 + - GITLAB_SSH_PORT=10022 + - GITLAB_RELATIVE_URL_ROOT= + - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string + - GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alphanumeric-string + - GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alphanumeric-string + + - GITLAB_ROOT_PASSWORD= + - GITLAB_ROOT_EMAIL= + + - GITLAB_NOTIFY_ON_BROKEN_BUILDS=true + - GITLAB_NOTIFY_PUSHER=false + + - GITLAB_EMAIL=notifications@example.com + - GITLAB_EMAIL_REPLY_TO=noreply@example.com + - GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com + + - GITLAB_BACKUP_SCHEDULE=daily + - GITLAB_BACKUP_TIME=01:00 + + - SMTP_ENABLED=false + - SMTP_DOMAIN=www.example.com + - SMTP_HOST=smtp.gmail.com + - SMTP_PORT=587 + - SMTP_USER=mailer@example.com + - SMTP_PASS=password + - SMTP_STARTTLS=true + - SMTP_AUTHENTICATION=login + + - IMAP_ENABLED=false + - IMAP_HOST=imap.gmail.com + - IMAP_PORT=993 + - IMAP_USER=mailer@example.com + - IMAP_PASS=password + - IMAP_SSL=true + - IMAP_STARTTLS=false + + - OAUTH_ENABLED=true + - OAUTH_AUTO_SIGN_IN_WITH_PROVIDER=Keycloak + - OAUTH_ALLOW_SSO=Keycloak + - OAUTH_BLOCK_AUTO_CREATED_USERS=false + - OAUTH_AUTO_LINK_LDAP_USER=false + - OAUTH_AUTO_LINK_SAML_USER=false + - OAUTH_EXTERNAL_PROVIDERS=Keycloak + + - OAUTH_CAS3_LABEL=cas3 + - OAUTH_CAS3_SERVER= + - OAUTH_CAS3_DISABLE_SSL_VERIFICATION=false + - OAUTH_CAS3_LOGIN_URL=/cas/login + - OAUTH_CAS3_VALIDATE_URL=/cas/p3/serviceValidate + - OAUTH_CAS3_LOGOUT_URL=/cas/logout + + - OAUTH_GOOGLE_API_KEY= + - OAUTH_GOOGLE_APP_SECRET= + - OAUTH_GOOGLE_RESTRICT_DOMAIN= + + - OAUTH_FACEBOOK_API_KEY= + - OAUTH_FACEBOOK_APP_SECRET= + + - OAUTH_TWITTER_API_KEY= + - OAUTH_TWITTER_APP_SECRET= + + - OAUTH_GITHUB_API_KEY= + - OAUTH_GITHUB_APP_SECRET= + - OAUTH_GITHUB_URL= + - OAUTH_GITHUB_VERIFY_SSL= + + - OAUTH_GITLAB_API_KEY= + - OAUTH_GITLAB_APP_SECRET= + + - OAUTH_BITBUCKET_API_KEY= + - OAUTH_BITBUCKET_APP_SECRET= + + - OAUTH_SAML_ASSERTION_CONSUMER_SERVICE_URL= + - OAUTH_SAML_IDP_CERT_FINGERPRINT= + - OAUTH_SAML_IDP_SSO_TARGET_URL= + - OAUTH_SAML_ISSUER= + - OAUTH_SAML_LABEL="Our SAML Provider" + - OAUTH_SAML_NAME_IDENTIFIER_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:transient + - OAUTH_SAML_GROUPS_ATTRIBUTE= + - OAUTH_SAML_EXTERNAL_GROUPS= + - OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL= + - OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME= + - OAUTH_SAML_ATTRIBUTE_STATEMENTS_USERNAME= + - OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME= + - OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME= + + - OAUTH_CROWD_SERVER_URL= + - OAUTH_CROWD_APP_NAME= + - OAUTH_CROWD_APP_PASSWORD= + + - OAUTH_AUTH0_CLIENT_ID= + - OAUTH_AUTH0_CLIENT_SECRET= + - OAUTH_AUTH0_DOMAIN= + - OAUTH_AUTH0_SCOPE= + + - OAUTH_AZURE_API_KEY= + - OAUTH_AZURE_API_SECRET= + - OAUTH_AZURE_TENANT_ID= + + - OAUTH2_GENERIC_APP_ID=git + - OAUTH2_GENERIC_APP_SECRET= + - OAUTH2_GENERIC_CLIENT_SITE=http://:10081 + - OAUTH2_GENERIC_CLIENT_USER_INFO_URL=http://:10081/auth/realms/master/protocol/openid-connect/userinfo + - OAUTH2_GENERIC_CLIENT_AUTHORIZE_URL=http://:10081/auth/realms/master/protocol/openid-connect/auth + - OAUTH2_GENERIC_CLIENT_TOKEN_URL=http://:10081/auth/realms/master/protocol/openid-connect/token + - OAUTH2_GENERIC_CLIENT_END_SESSION_ENDPOINT=http://:10081/auth/realms/master/protocol/openid-connect/logout + - OAUTH2_GENERIC_ID_PATH=sub + - OAUTH2_GENERIC_USER_UID=sub + - OAUTH2_GENERIC_USER_NAME=preferred_username + - OAUTH2_GENERIC_USER_EMAIL=email + - OAUTH2_GENERIC_NAME=Keycloak + + keycloak: + restart: always + image: jboss/keycloak:8.0.1 + ports: + - "10081:8080" + environment: + - DEBUG=false + - KEYCLOAK_PASSWORD=admin + - KEYCLOAK_USER=admin + +volumes: + redis-data: + postgresql-data: + gitlab-data: \ No newline at end of file diff --git a/docs/images/keycloak-admin-acc.png b/docs/images/keycloak-admin-acc.png new file mode 100644 index 00000000..11696725 Binary files /dev/null and b/docs/images/keycloak-admin-acc.png differ diff --git a/docs/images/keycloak-client-creation.png b/docs/images/keycloak-client-creation.png new file mode 100644 index 00000000..0595b8df Binary files /dev/null and b/docs/images/keycloak-client-creation.png differ diff --git a/docs/images/keycloak-client-creation2.png b/docs/images/keycloak-client-creation2.png new file mode 100644 index 00000000..96879a04 Binary files /dev/null and b/docs/images/keycloak-client-creation2.png differ diff --git a/docs/images/keycloak-client.png b/docs/images/keycloak-client.png new file mode 100644 index 00000000..f10fc95c Binary files /dev/null and b/docs/images/keycloak-client.png differ diff --git a/docs/images/keycloak-gitlab-login.png b/docs/images/keycloak-gitlab-login.png new file mode 100644 index 00000000..2d7933d6 Binary files /dev/null and b/docs/images/keycloak-gitlab-login.png differ diff --git a/docs/images/keycloak-home.png b/docs/images/keycloak-home.png new file mode 100644 index 00000000..f2adbed2 Binary files /dev/null and b/docs/images/keycloak-home.png differ diff --git a/docs/images/keycloak-secret.png b/docs/images/keycloak-secret.png new file mode 100644 index 00000000..4af4960e Binary files /dev/null and b/docs/images/keycloak-secret.png differ diff --git a/docs/images/keycloak-users.png b/docs/images/keycloak-users.png new file mode 100644 index 00000000..6949e821 Binary files /dev/null and b/docs/images/keycloak-users.png differ diff --git a/docs/keycloak-idp.md b/docs/keycloak-idp.md new file mode 100644 index 00000000..23f3eb08 --- /dev/null +++ b/docs/keycloak-idp.md @@ -0,0 +1,65 @@ +# Integrate Keycloak as a IDP with GitLab + +In this document, we will explain how to set up Keycloak and integrate it into GitLab. + +## Setting up Keycloak + +First, you need a client in Keycloak to authenticate with GitLab. You can start Keycloak by running `docker-compose up -d keycloak`. + +When Keycloak is running, log in using the `Administration console`. You can visit the Keycloak on the [local IP](http://localhost:10081) of your laptop. + +![Keycloak Home](images/keycloak-home.png) + +Next, create a client. + +![Keycloak client](images/keycloak-client.png) + +Fill in the following variables: + +![Keycloak client creation](images/keycloak-client-creation.png) + +Make access type confidential and enable service accounts and authorization. + +![Keycloak client creation](images/keycloak-client-creation2.png) + +Next, click save, get the client secret generated by Keycloak and start filling out the variables for GitLab in the docker-compose file. + +![Keycloak client secret](images/keycloak-secret.png) + +```yaml + - OAUTH2_GENERIC_APP_SECRET= + - OAUTH2_GENERIC_CLIENT_SITE=http://:10081 + - OAUTH2_GENERIC_CLIENT_USER_INFO_URL=http://:10081/auth/realms/master/protocol/openid-connect/userinfo + - OAUTH2_GENERIC_CLIENT_AUTHORIZE_URL=http://:10081/auth/realms/master/protocol/openid-connect/auth + - OAUTH2_GENERIC_CLIENT_TOKEN_URL=http://:10081/auth/realms/master/protocol/openid-connect/token + - OAUTH2_GENERIC_CLIENT_END_SESSION_ENDPOINT=http://:10081/auth/realms/master/protocol/openid-connect/logout +``` + +Make sure the following variables are filled in the docker-compose file: + +```yaml + - GITLAB_HOST='' + ... + - OAUTH_ENABLED=true + - OAUTH_AUTO_SIGN_IN_WITH_PROVIDER=Keycloak + - OAUTH_ALLOW_SSO=Keycloak + - OAUTH_BLOCK_AUTO_CREATED_USERS=false + - OAUTH_AUTO_LINK_LDAP_USER=false + - OAUTH_AUTO_LINK_SAML_USER=false + - OAUTH_EXTERNAL_PROVIDERS=Keycloak +``` + +GitLab does not allow login from users in Keycloak with an empty email or name. To prevent this, you can create a new user in Keycloak or you can add email and name for the admin account. + +Visit the `Users` tab and click on `View all users` to modify the Admin user. + +![keycloak-users](images/keycloak-users.png) + +Modify the `Email`, `First name` and `Last Name` fields. +![admin-account](images/keycloak-admin-acc.png) + +Deploy GitLab, Reddis and PostgreSQL by running the following command: `docker-compose up -d gitlab redis postgresql`. + +You can now login on the local GitLab instance with with Keycloak on your [local IP](http://localhost:10080). + +![gitlab-login](images/keycloak-gitlab-login.png) \ No newline at end of file