wp-openid-connect-server icon indicating copy to clipboard operation
wp-openid-connect-server copied to clipboard

How to add email claim using oidc_user_claims ?

Open funkypenguin opened this issue 2 years ago • 5 comments

Hey folks!

I'm trying to use this in conjection with https://github.com/mesosphere/traefik-forward-auth - I need an email claim to validate, so I tried the following client setup:

add_filter( 'oidc_registered_clients', 'my_oidc_clients' );
function my_oidc_clients() {
	return array(
		'clientid' => array(
			'name' => 'My Awesome Name',
			'secret' => 'clientsecret',
			'grant_types' => array( 'authorization_code' ),
			'scope' => 'openid profile email'
		),
	);
}

And then I added:

add_filter( 'oidc_user_claims', 'my_user_claims', 10, 2 );
function my_user_claims($claims, $user) {
    $claims['email'] = $user->user_email; 
    return $claims;
}

Hoping to get the email address returned. However, my claim (when debugged with https://openidconnect.net/), doesn't show the email field.

Have I misunderstood how to achieve this? :)

Thanks! D

funkypenguin avatar Jul 07 '23 02:07 funkypenguin

Hi, That's totally correct & should work. I am not familiar with Traefik forward auth setup, so that could have something to do here. This would require deeper debugging of exact data returned by endpoints vs expectations, in your setup. https://oauth.tools/ would be helpful here.

ashfame avatar Jul 07 '23 08:07 ashfame

I used openidconnect.net (so avoiding traefik-forward-auth), and confirmed that I the jtw didn't include an email claim, even though I asked for it (config above).

I'm not sure, but could it be related to https://github.com/Automattic/wp-openid-connect-server/blob/main/src/Http/Handlers/ConfigurationHandler.php#L31 ?

D

funkypenguin avatar Jul 07 '23 08:07 funkypenguin

Been debugging this a bit.. adding this die() code in src/Storage/UserClaimsStorage.php doesn't seem to get executed, i expect the entire function isn't being called for some reason...

class UserClaimsStorage implements UserClaimsInterface {
	public function getUserClaims( $user_id, $scope ) {
		die('to be clear, this is never executed');

funkypenguin avatar Jul 09 '23 05:07 funkypenguin

AFAICT, the getUserClaims() method is called when a request is made to either the authorize endpoint or the userinfo endpoint.

psrpinto avatar Jul 10 '23 12:07 psrpinto

I don't understand enough to know why, but I found that I needed to edit buildAuthorizeParameters in openid-connect-server/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/AuthorizeController.php, and insert this:

		$user = get_user_by( 'login', $user_id );
		$field_map = array(
			'email'    => 'user_email',
		);

		foreach ( $field_map as $key => $value ) {
			if ( $user->$value ) {
				$claims[ $key ] = $user->$value;
			}
		}

Before this, (to which I added the $claims variable):

        if ($this->needsIdToken($this->getScope()) && $this->getResponseType() == self::RESPONSE_TYPE_AUTHORIZATION_CODE) {
            $params['id_token'] = $this->responseTypes['id_token']->createIdToken($this->getClientId(), $user_id, $this->nonce, $claims);
        }

It's working, but I'll happily take instruction on why, and how I could have done it better :)

funkypenguin avatar Jul 10 '23 14:07 funkypenguin