|
|
|
@ -1,34 +1,115 @@
|
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Plugin OIDC/oAuth client class.
|
|
|
|
|
*
|
|
|
|
|
* @package OpenID_Connect_Generic
|
|
|
|
|
* @category Authentication
|
|
|
|
|
* @author Jonathan Daggerhart <jonathan@daggerhart.com>
|
|
|
|
|
* @copyright 2015-2020 daggerhart
|
|
|
|
|
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* OpenID_Connect_Generic_Client class.
|
|
|
|
|
*
|
|
|
|
|
* Plugin OIDC/oAuth client class.
|
|
|
|
|
*
|
|
|
|
|
* @package OpenID_Connect_Generic
|
|
|
|
|
* @category Authentication
|
|
|
|
|
*/
|
|
|
|
|
class OpenID_Connect_Generic_Client {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The OIDC/oAuth client ID.
|
|
|
|
|
*
|
|
|
|
|
* @see OpenID_Connect_Generic_Option_Settings::client_id
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
private $client_id;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The OIDC/oAuth client secret.
|
|
|
|
|
*
|
|
|
|
|
* @see OpenID_Connect_Generic_Option_Settings::client_secret
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
private $client_secret;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The OIDC/oAuth scopes.
|
|
|
|
|
*
|
|
|
|
|
* @see OpenID_Connect_Generic_Option_Settings::scope
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
private $scope;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The OIDC/oAuth authorization endpoint URL.
|
|
|
|
|
*
|
|
|
|
|
* @see OpenID_Connect_Generic_Option_Settings::endpoint_login
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
private $endpoint_login;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The OIDC/oAuth User Information endpoint URL.
|
|
|
|
|
*
|
|
|
|
|
* @see OpenID_Connect_Generic_Option_Settings::endpoint_userinfo
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
private $endpoint_userinfo;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The OIDC/oAuth token validation endpoint URL.
|
|
|
|
|
*
|
|
|
|
|
* @see OpenID_Connect_Generic_Option_Settings::endpoint_token
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
private $endpoint_token;
|
|
|
|
|
|
|
|
|
|
// login flow "ajax" endpoint
|
|
|
|
|
/**
|
|
|
|
|
* The login flow "ajax" endpoint URI.
|
|
|
|
|
*
|
|
|
|
|
* @see OpenID_Connect_Generic_Option_Settings::redirect_uri
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
private $redirect_uri;
|
|
|
|
|
|
|
|
|
|
// states are only valid for 3 minutes
|
|
|
|
|
/**
|
|
|
|
|
* The state time limit. States are only valid for 3 minutes.
|
|
|
|
|
*
|
|
|
|
|
* @see OpenID_Connect_Generic_Option_Settings::state_time_limit
|
|
|
|
|
*
|
|
|
|
|
* @var int
|
|
|
|
|
*/
|
|
|
|
|
private $state_time_limit = 180;
|
|
|
|
|
|
|
|
|
|
// logger object
|
|
|
|
|
/**
|
|
|
|
|
* The logger object instance.
|
|
|
|
|
*
|
|
|
|
|
* @var OpenID_Connect_Generic_Option_Logger
|
|
|
|
|
*/
|
|
|
|
|
private $logger;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Client constructor
|
|
|
|
|
*
|
|
|
|
|
* @param $client_id
|
|
|
|
|
* @param $client_secret
|
|
|
|
|
* @param $scope
|
|
|
|
|
* @param $endpoint_login
|
|
|
|
|
* @param $endpoint_userinfo
|
|
|
|
|
* @param $endpoint_token
|
|
|
|
|
* @param $redirect_uri
|
|
|
|
|
* @param $state_time_limit time states are valid in seconds
|
|
|
|
|
* Client constructor.
|
|
|
|
|
*
|
|
|
|
|
* @param string $client_id @see OpenID_Connect_Generic_Option_Settings::client_id for description.
|
|
|
|
|
* @param string $client_secret @see OpenID_Connect_Generic_Option_Settings::client_secret for description.
|
|
|
|
|
* @param string $scope @see OpenID_Connect_Generic_Option_Settings::scope for description.
|
|
|
|
|
* @param string $endpoint_login @see OpenID_Connect_Generic_Option_Settings::endpoint_login for description.
|
|
|
|
|
* @param string $endpoint_userinfo @see OpenID_Connect_Generic_Option_Settings::endpoint_userinfo for description.
|
|
|
|
|
* @param string $endpoint_token @see OpenID_Connect_Generic_Option_Settings::endpoint_token for description.
|
|
|
|
|
* @param string $redirect_uri @see OpenID_Connect_Generic_Option_Settings::redirect_uri for description.
|
|
|
|
|
* @param int $state_time_limit @see OpenID_Connect_Generic_Option_Settings::state_time_limit for description.
|
|
|
|
|
* @param OpenID_Connect_Generic_Option_Logger $logger The plugin logging object instance.
|
|
|
|
|
*/
|
|
|
|
|
function __construct( $client_id, $client_secret, $scope, $endpoint_login, $endpoint_userinfo, $endpoint_token, $redirect_uri, $state_time_limit, $logger ) {
|
|
|
|
|
$this->client_id = $client_id;
|
|
|
|
@ -77,22 +158,22 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
/**
|
|
|
|
|
* Validate the request for login authentication
|
|
|
|
|
*
|
|
|
|
|
* @param $request
|
|
|
|
|
* @param array $request The authentication request results.
|
|
|
|
|
*
|
|
|
|
|
* @return array|\WP_Error
|
|
|
|
|
* @return array|WP_Error
|
|
|
|
|
*/
|
|
|
|
|
function validate_authentication_request( $request ) {
|
|
|
|
|
// look for an existing error of some kind
|
|
|
|
|
// Look for an existing error of some kind.
|
|
|
|
|
if ( isset( $request['error'] ) ) {
|
|
|
|
|
return new WP_Error( 'unknown-error', 'An unknown error occurred.', $request );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// make sure we have a legitimate authentication code and valid state
|
|
|
|
|
// Make sure we have a legitimate authentication code and valid state.
|
|
|
|
|
if ( ! isset( $request['code'] ) ) {
|
|
|
|
|
return new WP_Error( 'no-code', 'No authentication code present in the request.', $request );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// check the client request state
|
|
|
|
|
// Check the client request state.
|
|
|
|
|
if ( ! isset( $request['state'] ) ) {
|
|
|
|
|
do_action( 'openid-connect-generic-no-state-provided' );
|
|
|
|
|
return new WP_Error( 'missing-state', __( 'Missing state.' ), $request );
|
|
|
|
@ -108,24 +189,24 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
/**
|
|
|
|
|
* Get the authorization code from the request
|
|
|
|
|
*
|
|
|
|
|
* @param $request array
|
|
|
|
|
* @param array $request The authentication request results.
|
|
|
|
|
*
|
|
|
|
|
* @return string|\WP_Error
|
|
|
|
|
* @return string|WP_Error
|
|
|
|
|
*/
|
|
|
|
|
function get_authentication_code( $request ) {
|
|
|
|
|
return $request['code'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Using the authorization_code, request an authentication token from the idp
|
|
|
|
|
* Using the authorization_code, request an authentication token from the IDP.
|
|
|
|
|
*
|
|
|
|
|
* @param $code - authorization_code
|
|
|
|
|
* @param string $code The authorization code.
|
|
|
|
|
*
|
|
|
|
|
* @return array|\WP_Error
|
|
|
|
|
* @return array|WP_Error
|
|
|
|
|
*/
|
|
|
|
|
function request_authentication_token( $code ) {
|
|
|
|
|
|
|
|
|
|
// Add Host header - required for when the openid-connect endpoint is behind a reverse-proxy
|
|
|
|
|
// Add Host header - required for when the openid-connect endpoint is behind a reverse-proxy.
|
|
|
|
|
$parsed_url = parse_url( $this->endpoint_token );
|
|
|
|
|
$host = $parsed_url['host'];
|
|
|
|
|
|
|
|
|
@ -141,10 +222,10 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
'headers' => array( 'Host' => $host ),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// allow modifications to the request
|
|
|
|
|
// Allow modifications to the request.
|
|
|
|
|
$request = apply_filters( 'openid-connect-generic-alter-request', $request, 'get-authentication-token' );
|
|
|
|
|
|
|
|
|
|
// call the server and ask for a token
|
|
|
|
|
// Call the server and ask for a token.
|
|
|
|
|
$this->logger->log( $this->endpoint_token, 'request_authentication_token' );
|
|
|
|
|
$response = wp_remote_post( $this->endpoint_token, $request );
|
|
|
|
|
|
|
|
|
@ -158,9 +239,9 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
/**
|
|
|
|
|
* Using the refresh token, request new tokens from the idp
|
|
|
|
|
*
|
|
|
|
|
* @param $refresh_token - refresh token previously obtained from token response.
|
|
|
|
|
* @param string $refresh_token The refresh token previously obtained from token response.
|
|
|
|
|
*
|
|
|
|
|
* @return array|\WP_Error
|
|
|
|
|
* @return array|WP_Error
|
|
|
|
|
*/
|
|
|
|
|
function request_new_tokens( $refresh_token ) {
|
|
|
|
|
$request = array(
|
|
|
|
@ -172,10 +253,10 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// allow modifications to the request
|
|
|
|
|
// Allow modifications to the request.
|
|
|
|
|
$request = apply_filters( 'openid-connect-generic-alter-request', $request, 'refresh-token' );
|
|
|
|
|
|
|
|
|
|
// call the server and ask for new tokens
|
|
|
|
|
// Call the server and ask for new tokens.
|
|
|
|
|
$this->logger->log( $this->endpoint_token, 'request_new_tokens' );
|
|
|
|
|
$response = wp_remote_post( $this->endpoint_token, $request );
|
|
|
|
|
|
|
|
|
@ -189,17 +270,23 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
/**
|
|
|
|
|
* Extract and decode the token body of a token response
|
|
|
|
|
*
|
|
|
|
|
* @param $token_result
|
|
|
|
|
* @return array|mixed|object
|
|
|
|
|
* @param array $token_result The token response.
|
|
|
|
|
*
|
|
|
|
|
* @return array|WP_Error|null
|
|
|
|
|
*/
|
|
|
|
|
function get_token_response( $token_result ) {
|
|
|
|
|
if ( ! isset( $token_result['body'] ) ) {
|
|
|
|
|
return new WP_Error( 'missing-token-body', __( 'Missing token body.' ), $token_result );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// extract token response from token
|
|
|
|
|
// Extract the token response from token.
|
|
|
|
|
$token_response = json_decode( $token_result['body'], true );
|
|
|
|
|
|
|
|
|
|
// Check that the token response body was able to be parsed.
|
|
|
|
|
if ( is_null( $token_response ) ) {
|
|
|
|
|
return new WP_Error( 'invalid-token', __( 'Invalid token.' ), $token_result );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( isset( $token_response['error'] ) ) {
|
|
|
|
|
$error = $token_response['error'];
|
|
|
|
|
$error_description = $error;
|
|
|
|
@ -212,27 +299,28 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
return $token_response;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Exchange an access_token for a user_claim from the userinfo endpoint
|
|
|
|
|
*
|
|
|
|
|
* @param $access_token
|
|
|
|
|
* @param string $access_token The access token supplied from authentication user claim.
|
|
|
|
|
*
|
|
|
|
|
* @return array|\WP_Error
|
|
|
|
|
* @return array|WP_Error
|
|
|
|
|
*/
|
|
|
|
|
function request_userinfo( $access_token ) {
|
|
|
|
|
// allow modifications to the request
|
|
|
|
|
// Allow modifications to the request.
|
|
|
|
|
$request = apply_filters( 'openid-connect-generic-alter-request', array(), 'get-userinfo' );
|
|
|
|
|
|
|
|
|
|
// section 5.3.1 of the spec recommends sending the access token using the authorization header
|
|
|
|
|
// a filter may or may not have already added headers - make sure they exist then add the token
|
|
|
|
|
/*
|
|
|
|
|
* Section 5.3.1 of the spec recommends sending the access token using the authorization header
|
|
|
|
|
* a filter may or may not have already added headers - make sure they exist then add the token.
|
|
|
|
|
*/
|
|
|
|
|
if ( ! array_key_exists( 'headers', $request ) || ! is_array( $request['headers'] ) ) {
|
|
|
|
|
$request['headers'] = array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$request['headers']['Authorization'] = 'Bearer ' . $access_token;
|
|
|
|
|
|
|
|
|
|
// Add Host header - required for when the openid-connect endpoint is behind a reverse-proxy
|
|
|
|
|
// Add Host header - required for when the openid-connect endpoint is behind a reverse-proxy.
|
|
|
|
|
$parsed_url = parse_url( $this->endpoint_userinfo );
|
|
|
|
|
$host = $parsed_url['host'];
|
|
|
|
|
|
|
|
|
@ -242,7 +330,7 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
|
|
|
|
|
$request['headers']['Host'] = $host;
|
|
|
|
|
|
|
|
|
|
// attempt the request including the access token in the query string for backwards compatibility
|
|
|
|
|
// Attempt the request including the access token in the query string for backwards compatibility.
|
|
|
|
|
$this->logger->log( $this->endpoint_userinfo, 'request_userinfo' );
|
|
|
|
|
$response = wp_remote_post( $this->endpoint_userinfo, $request );
|
|
|
|
|
|
|
|
|
@ -254,13 +342,12 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generate a new state, save it as a transient,
|
|
|
|
|
* and return the state hash.
|
|
|
|
|
* Generate a new state, save it as a transient, and return the state hash.
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
function new_state() {
|
|
|
|
|
// new state w/ timestamp
|
|
|
|
|
// New state w/ timestamp.
|
|
|
|
|
$state = md5( mt_rand() . microtime( true ) );
|
|
|
|
|
set_transient( 'openid-connect-generic-state--' . $state, $state, $this->state_time_limit );
|
|
|
|
|
|
|
|
|
@ -270,7 +357,7 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
/**
|
|
|
|
|
* Check the existence of a given state transient.
|
|
|
|
|
*
|
|
|
|
|
* @param $state
|
|
|
|
|
* @param string $state The state hash to validate.
|
|
|
|
|
*
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
@ -293,15 +380,17 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Ensure that the token meets basic requirements
|
|
|
|
|
* Ensure that the token meets basic requirements.
|
|
|
|
|
*
|
|
|
|
|
* @param $token_response
|
|
|
|
|
* @param array $token_response The token response.
|
|
|
|
|
*
|
|
|
|
|
* @return bool|\WP_Error
|
|
|
|
|
* @return bool|WP_Error
|
|
|
|
|
*/
|
|
|
|
|
function validate_token_response( $token_response ) {
|
|
|
|
|
// we need to ensure 2 specific items exist with the token response in order
|
|
|
|
|
// to proceed with confidence: id_token and token_type == 'Bearer'
|
|
|
|
|
/*
|
|
|
|
|
* Ensure 2 specific items exist with the token response in order
|
|
|
|
|
* to proceed with confidence: id_token and token_type == 'Bearer'
|
|
|
|
|
*/
|
|
|
|
|
if ( ! isset( $token_response['id_token'] ) ||
|
|
|
|
|
! isset( $token_response['token_type'] ) || strcasecmp( $token_response['token_type'], 'Bearer' )
|
|
|
|
|
) {
|
|
|
|
@ -312,29 +401,29 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Extract the id_token_claim from the token_response
|
|
|
|
|
* Extract the id_token_claim from the token_response.
|
|
|
|
|
*
|
|
|
|
|
* @param $token_response
|
|
|
|
|
* @param array $token_response The token response.
|
|
|
|
|
*
|
|
|
|
|
* @return array|\WP_Error
|
|
|
|
|
* @return array|WP_Error
|
|
|
|
|
*/
|
|
|
|
|
function get_id_token_claim( $token_response ) {
|
|
|
|
|
// name sure we have an id_token
|
|
|
|
|
// Validate there is an id_token.
|
|
|
|
|
if ( ! isset( $token_response['id_token'] ) ) {
|
|
|
|
|
return new WP_Error( 'no-identity-token', __( 'No identity token' ), $token_response );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// break apart the id_token in the response for decoding
|
|
|
|
|
// Break apart the id_token in the response for decoding.
|
|
|
|
|
$tmp = explode( '.', $token_response['id_token'] );
|
|
|
|
|
|
|
|
|
|
if ( ! isset( $tmp[1] ) ) {
|
|
|
|
|
return new WP_Error( 'missing-identity-token', __( 'Missing identity token' ), $token_response );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Extract the id_token's claims from the token
|
|
|
|
|
// Extract the id_token's claims from the token.
|
|
|
|
|
$id_token_claim = json_decode(
|
|
|
|
|
base64_decode(
|
|
|
|
|
str_replace( // because token is encoded in base64 URL (and not just base64)
|
|
|
|
|
str_replace( // Because token is encoded in base64 URL (and not just base64).
|
|
|
|
|
array( '-', '_' ),
|
|
|
|
|
array( '+', '/' ),
|
|
|
|
|
$tmp[1]
|
|
|
|
@ -347,18 +436,18 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Ensure the id_token_claim contains the required values
|
|
|
|
|
* Ensure the id_token_claim contains the required values.
|
|
|
|
|
*
|
|
|
|
|
* @param $id_token_claim
|
|
|
|
|
* @param array $id_token_claim The ID token claim.
|
|
|
|
|
*
|
|
|
|
|
* @return bool|\WP_Error
|
|
|
|
|
* @return bool|WP_Error
|
|
|
|
|
*/
|
|
|
|
|
function validate_id_token_claim( $id_token_claim ) {
|
|
|
|
|
if ( ! is_array( $id_token_claim ) ) {
|
|
|
|
|
return new WP_Error( 'bad-id-token-claim', __( 'Bad ID token claim' ), $id_token_claim );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// make sure we can find our identification data and that it has a value
|
|
|
|
|
// Validate the identification data and it's value.
|
|
|
|
|
if ( ! isset( $id_token_claim['sub'] ) || empty( $id_token_claim['sub'] ) ) {
|
|
|
|
|
return new WP_Error( 'no-subject-identity', __( 'No subject identity' ), $id_token_claim );
|
|
|
|
|
}
|
|
|
|
@ -367,17 +456,17 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Attempt to exchange the access_token for a user_claim
|
|
|
|
|
* Attempt to exchange the access_token for a user_claim.
|
|
|
|
|
*
|
|
|
|
|
* @param $token_response
|
|
|
|
|
* @param array $token_response The token response.
|
|
|
|
|
*
|
|
|
|
|
* @return array|mixed|object|\WP_Error
|
|
|
|
|
* @return array|WP_Error|null
|
|
|
|
|
*/
|
|
|
|
|
function get_user_claim( $token_response ) {
|
|
|
|
|
// send a userinfo request to get user claim
|
|
|
|
|
// Send a userinfo request to get user claim.
|
|
|
|
|
$user_claim_result = $this->request_userinfo( $token_response['access_token'] );
|
|
|
|
|
|
|
|
|
|
// make sure we didn't get an error, and that the response body exists
|
|
|
|
|
// Make sure we didn't get an error, and that the response body exists.
|
|
|
|
|
if ( is_wp_error( $user_claim_result ) || ! isset( $user_claim_result['body'] ) ) {
|
|
|
|
|
return new WP_Error( 'bad-claim', __( 'Bad user claim' ), $user_claim_result );
|
|
|
|
|
}
|
|
|
|
@ -391,18 +480,18 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
* Make sure the user_claim has all required values, and that the subject
|
|
|
|
|
* identity matches of the id_token matches that of the user_claim.
|
|
|
|
|
*
|
|
|
|
|
* @param $user_claim
|
|
|
|
|
* @param $id_token_claim
|
|
|
|
|
* @param array $user_claim The authentication user claim.
|
|
|
|
|
* @param array $id_token_claim The ID token claim.
|
|
|
|
|
*
|
|
|
|
|
* @return \WP_Error
|
|
|
|
|
* @return bool|WP_Error
|
|
|
|
|
*/
|
|
|
|
|
function validate_user_claim( $user_claim, $id_token_claim ) {
|
|
|
|
|
// must be an array
|
|
|
|
|
// Validate the user claim.
|
|
|
|
|
if ( ! is_array( $user_claim ) ) {
|
|
|
|
|
return new WP_Error( 'invalid-user-claim', __( 'Invalid user claim' ), $user_claim );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// allow for errors from the IDP
|
|
|
|
|
// Allow for errors from the IDP.
|
|
|
|
|
if ( isset( $user_claim['error'] ) ) {
|
|
|
|
|
$message = __( 'Error from the IDP' );
|
|
|
|
|
if ( ! empty( $user_claim['error_description'] ) ) {
|
|
|
|
@ -411,12 +500,12 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
return new WP_Error( 'invalid-user-claim-' . $user_claim['error'], $message, $user_claim );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// make sure the id_token sub === user_claim sub, according to spec
|
|
|
|
|
// Make sure the id_token sub equals the user_claim sub, according to spec.
|
|
|
|
|
if ( $id_token_claim['sub'] !== $user_claim['sub'] ) {
|
|
|
|
|
return new WP_Error( 'incorrect-user-claim', __( 'Incorrect user claim' ), func_get_args() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// allow for other plugins to alter the login success
|
|
|
|
|
// Allow for other plugins to alter the login success.
|
|
|
|
|
$login_user = apply_filters( 'openid-connect-generic-user-login-test', true, $user_claim );
|
|
|
|
|
|
|
|
|
|
if ( ! $login_user ) {
|
|
|
|
@ -427,13 +516,14 @@ class OpenID_Connect_Generic_Client {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Retrieve the subject identity from the id_token
|
|
|
|
|
* Retrieve the subject identity from the id_token.
|
|
|
|
|
*
|
|
|
|
|
* @param $id_token_claim array
|
|
|
|
|
* @param array $id_token_claim The ID token claim.
|
|
|
|
|
*
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
function get_subject_identity( $id_token_claim ) {
|
|
|
|
|
return $id_token_claim['sub'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|