Because I found it frustratingly hard to make GitLab and dex talk to each other, this article walks you through what I did step-by-step.
Let’s establish some terminology:
-
dex is our OpenID Connect (OIDC) “Provider (OP)”
in other words: the component which verifies usernames and passwords. -
GitLab is our OpenID Connect (OIDC) “Relying Party (RP)”
in other words: the component where the user actually wants to log in.
Step 1: configure dex
First, I followed dex’s Getting started guide until I had dex serving the example config.
Then, I made the following changes to examples/config-dev.yaml:
- Change the issuer URL to be fully qualified and use HTTPS.
- Configure the HTTPS listener.
- Configure GitLab’s redirect URI.
Here is a diff:
--- /proc/self/fd/11 2017-10-21 15:01:49.005587935 +0200
+++ /tmp/config-dev.yaml 2017-10-21 15:01:47.121632025 +0200
@@ -1,7 +1,7 @@
# The base path of dex and the external name of the OpenID Connect service.
# This is the canonical URL that all clients MUST use to refer to dex. If a
# path is provided, dex's HTTP service will listen at a non-root URL.
-issuer: http://127.0.0.1:5556/dex
+issuer: https://dex.example.net:5554/dex
# The storage configuration determines where dex stores its state. Supported
# options include SQL flavors and Kubernetes third party resources.
@@ -14,11 +14,9 @@
# Configuration for the HTTP endpoints.
web:
- http: 0.0.0.0:5556
- # Uncomment for HTTPS options.
- # https: 127.0.0.1:5554
- # tlsCert: /etc/dex/tls.crt
- # tlsKey: /etc/dex/tls.key
+ https: dex.example.net:5554
+ tlsCert: /etc/letsencrypt/live/dex.example.net/fullchain.pem
+ tlsKey: /etc/letsencrypt/live/dex.example.net/privkey.pem
# Uncomment this block to enable the gRPC API. This values MUST be different
# from the HTTP endpoints.
@@ -50,7 +48,7 @@
staticClients:
- id: example-app
redirectURIs:
- - 'http://127.0.0.1:5555/callback'
+ - 'http://gitlab.example.net/users/auth/mydex/callback'
name: 'Example App'
secret: ZXhhbXBsZS1hcHAtc2VjcmV0
Step 2: configure GitLab
First, I followed GitLab Docker images to get GitLab running in Docker.
Then, I swapped out the image with computersciencehouse/gitlab-ce-oidc, which is based on the official image, but adds OpenID Connect support.
I added the following config to /srv/gitlab/config/gitlab.rb
:
gitlab_rails['omniauth_enabled'] = true
# Must match the args.name (!) of our configured omniauth provider:
gitlab_rails['omniauth_allow_single_sign_on'] = ['mydex']
# By default, third-party authentication results in a newly created
# user which needs to be unblocked by an admin. Disable this
# additional safety mechanism and directly create users:
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_providers'] = [
{
name: 'openid_connect', # identifies the omniauth gem to use
label: 'OIDC',
args: {
# The name shows up in the GitLab UI in title-case, i.e. “Mydex”,
# and must match the name in client_options.redirect_uri below
# and omniauth_allow_single_sign_on above.
#
# NOTE that if you change the name after users have already
# signed up through the provider, you will need to update the
# “identities” PostgreSQL table accordingly:
# echo "UPDATE identities SET provider = 'newdex' WHERE \
# provider = 'mydex';" | gitlab-psql gitlabhq_production
'name': 'mydex',
# Scope must contain “email”.
'scope': ['openid', 'profile', 'email'],
# Discover all endpoints from the issuer, specifically from
# https://dex.example.net:5554/dex/.well-known/openid-configuration
'discovery': true,
# Must match the issuer configured in dex:
# Note that http:// URLs did not work in my tests; use https://
'issuer': 'https://dex.example.net:5554/dex',
'client_options': {
# identifier, secret and redirect_uri must match a
# configured client in dex.
'identifier': 'example-app',
'secret': 'ZXhhbXBsZS1hcHAtc2VjcmV0',
'redirect_uri': 'https://gitlab.example.net/users/auth/mydex/callback'
}
}
}
]
Step 3: patch omniauth-openid-connect
Until dex issue #376 is fixed, the following patch for the omniauth-openid-connect gem is required:
--- /opt/gitlab/embedded/lib/ruby/gems/2.3.0/gems/omniauth-openid-connect-0.2.3/lib/omniauth/strategies/openid_connect.rb.orig 2017-10-21 12:31:50.777602847 +0000
+++ /opt/gitlab/embedded/lib/ruby/gems/2.3.0/gems/omniauth-openid-connect-0.2.3/lib/omniauth/strategies/openid_connect.rb 2017-10-21 12:34:20.063308560 +0000
@@ -42,24 +42,13 @@
option :send_nonce, true
option :client_auth_method
- uid { user_info.sub }
-
+ uid { @email }
info do
- {
- name: user_info.name,
- email: user_info.email,
- nickname: user_info.preferred_username,
- first_name: user_info.given_name,
- last_name: user_info.family_name,
- gender: user_info.gender,
- image: user_info.picture,
- phone: user_info.phone_number,
- urls: { website: user_info.website }
- }
+ { email: @email }
end
extra do
- {raw_info: user_info.raw_attributes}
+ {raw_info: {}}
end
credentials do
@@ -165,6 +154,7 @@
client_id: client_options.identifier,
nonce: stored_nonce
)
+ @email = _id_token.raw_attributes['email']
_access_token
}.call()
end
I run a blog since 2005, spreading knowledge and experience for almost 20 years! :)
If you want to support my work, you can buy me a coffee.
Thank you for your support! ❤️