Skip to content

Commit

Permalink
Merge pull request #255 from schanzen/aggregated_claims
Browse files Browse the repository at this point in the history
Aggregated claims
  • Loading branch information
timnolte authored Feb 25, 2022
2 parents 11494b4 + a58dd88 commit 6baee18
Showing 1 changed file with 72 additions and 2 deletions.
74 changes: 72 additions & 2 deletions includes/openid-connect-generic-client-wrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,75 @@ private function get_nickname_from_claim( $user_claim ) {
return $desired_nickname;
}

/**
* Checks if $claimname is in the body or _claim_names of the userinfo.
* If yes, returns the claim value. Otherwise, returns false.
*
* @param string $claimname the claim name to look for.
* @param array $userinfo the JSON to look in.
* @param string $claimvalue the source claim value ( from the body of the JWT of the claim source).
* @return true|false
*/
private function get_claim( $claimname, $userinfo, &$claimvalue ) {
/**
* If we find a simple claim, return it.
*/
if ( array_key_exists( $claimname, $userinfo ) ) {
$claimvalue = $userinfo[ $claimname ];
return true;
}
/**
* If there are no aggregated claims, it is over.
*/
if ( ! array_key_exists( '_claim_names', $userinfo ) ||
! array_key_exists( '_claim_sources', $userinfo ) ) {
return false;
}
$claim_src_ptr = $userinfo['_claim_names'];
if ( ! isset( $claim_src_ptr ) ) {
return false;
}
/**
* No reference found
*/
if ( ! array_key_exists( $claimname, $claim_src_ptr ) ) {
return false;
}
$src_name = $claim_src_ptr[ $claimname ];
// Reference found, but no corresponding JWT. This is a malformed userinfo.
if ( ! array_key_exists( $src_name, $userinfo['_claim_sources'] ) ) {
return false;
}
$src = $userinfo['_claim_sources'][ $src_name ];
// Source claim is not a JWT. Abort.
if ( ! array_key_exists( 'JWT', $src ) ) {
return false;
}
/**
* Extract claim from JWT.
* FIXME: We probably want to verify the JWT signature/issuer here.
* For example, using JWKS if applicable. For symmetrically signed
* JWTs (HMAC), we need a way to specify the acceptable secrets
* and each possible issuer in the config.
*/
$jwt = $src['JWT'];
list ( $header, $body, $rest ) = explode( '.', $jwt, 3 );
$body_str = base64_decode( $body, false );
if ( ! $body_str ) {
return false;
}
$body_json = json_decode( $body_str, true );
if ( ! isset( $body_json ) ) {
return false;
}
if ( ! array_key_exists( $claimname, $body_json ) ) {
return false;
}
$claimvalue = $body_json[ $claimname ];
return true;
}


/**
* Build a string from the user claim according to the specified format.
*
Expand All @@ -760,12 +829,13 @@ private function get_nickname_from_claim( $user_claim ) {
private function format_string_with_claim( $format, $user_claim, $error_on_missing_key = false ) {
$matches = null;
$string = '';
$info = '';
$i = 0;
if ( preg_match_all( '/\{[^}]*\}/u', $format, $matches, PREG_OFFSET_CAPTURE ) ) {
foreach ( $matches[0] as $match ) {
$key = substr( $match[0], 1, -1 );
$string .= substr( $format, $i, $match[1] - $i );
if ( ! isset( $user_claim[ $key ] ) ) {
if ( ! $this->get_claim( $key, $user_claim, $info ) ) {
if ( $error_on_missing_key ) {
return new WP_Error(
'incomplete-user-claim',
Expand All @@ -779,7 +849,7 @@ private function format_string_with_claim( $format, $user_claim, $error_on_missi
);
}
} else {
$string .= $user_claim[ $key ];
$string .= $info;
}
$i = $match[1] + strlen( $match[0] );
}
Expand Down

0 comments on commit 6baee18

Please sign in to comment.