Commit 729b5693 authored by André Hänsel's avatar André Hänsel

Add email and email_verified claims to OAuth ID tokens

This adds the "email" and "email_verified" claims to OAuth ID tokens.

This is to support OpenID Connect clients that expect the email address
in the ID token instead of the UserInfo endpoint.

Note that the claims are added to the ID token regardless of whether the
email scope is granted or not. This is currently a limitation of the
doorkeeper-openid_connect gem.
parent a078e802
---
title: Add email and email_verified claims to OAuth ID token
merge_request: 35468
author: André Hänsel
type: fixed
......@@ -37,10 +37,10 @@ Doorkeeper::OpenidConnect.configure do
# public email address (if present)
# This allows existing solutions built for GitLab's old behavior to keep
# working without modification.
o.claim(:email) do |user, scopes|
o.claim(:email, response: [:id_token, :user_info]) do |user, scopes|
scopes.exists?(:email) ? user.email : user.public_email
end
o.claim(:email_verified) do |user, scopes|
o.claim(:email_verified, response: [:id_token, :user_info]) do |user, scopes|
if scopes.exists?(:email)
user.primary_email_verified?
elsif user.public_email?
......
......@@ -37,11 +37,11 @@ Currently the following user information is shared with clients:
| `auth_time` | `integer` | The timestamp for the user's last authentication
| `name` | `string` | The user's full name
| `nickname` | `string` | The user's GitLab username
| `email` | `string` | The user's public email address
| `email_verified` | `boolean` | Whether the user's public email address was verified
| `email` | `string` | The user's email address<br>This is the user's *primary* email address if the application has access to the `email` claim and the user's *public* email address otherwise
| `email_verified` | `boolean` | Whether the user's email address was verified
| `website` | `string` | URL for the user's website
| `profile` | `string` | URL for the user's GitLab profile
| `picture` | `string` | URL for the user's GitLab avatar
| `groups` | `array` | Names of the groups the user is a member of
Only the `sub` and `sub_legacy` claims are included in the ID token, all other claims are available from the `/oauth/userinfo` endpoint used by OIDC clients.
The claims `sub`, `sub_legacy`, `email` and `email_verified` are included in the ID token, all other claims are available from the `/oauth/userinfo` endpoint used by OIDC clients.
......@@ -146,8 +146,16 @@ RSpec.describe 'OpenID Connect requests' do
expect(@payload['auth_time']).to eq user.current_sign_in_at.to_i
end
it 'has public email in email claim' do
expect(@payload['email']).to eq(user.public_email)
end
it 'has true in email_verified claim' do
expect(@payload['email_verified']).to eq(true)
end
it 'does not include any unknown properties' do
expect(@payload.keys).to eq %w[iss sub aud exp iat auth_time sub_legacy]
expect(@payload.keys).to eq %w[iss sub aud exp iat auth_time sub_legacy email email_verified]
end
end
......@@ -211,5 +219,20 @@ RSpec.describe 'OpenID Connect requests' do
expect(json_response['email_verified']).to eq(true)
end
end
context 'ID token payload' do
before do
request_access_token!
@payload = JSON::JWT.decode(json_response['id_token'], :skip_verification)
end
it 'has private email in email claim' do
expect(@payload['email']).to eq(user.email)
end
it 'has true in email_verified claim' do
expect(@payload['email_verified']).to eq(true)
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment