From 69930fcd3cbfde78d9cf9d3b18321c4d322206cc Mon Sep 17 00:00:00 2001 From: Raif Atef Date: Tue, 22 Nov 2016 20:20:08 +0200 Subject: [PATCH] OpenID Connect end_session_endpoint integrated logout support. --- .../openid-connect-generic-client-wrapper.php | 34 +++++++++++++++++++ .../openid-connect-generic-login-form.php | 7 +++- .../openid-connect-generic-settings-page.php | 7 ++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/includes/openid-connect-generic-client-wrapper.php b/includes/openid-connect-generic-client-wrapper.php index 02365d3..39f6059 100644 --- a/includes/openid-connect-generic-client-wrapper.php +++ b/includes/openid-connect-generic-client-wrapper.php @@ -47,6 +47,11 @@ class OpenID_Connect_Generic_Client_Wrapper { // remove cookies on logout add_action( 'wp_logout', array( $client_wrapper, 'wp_logout' ) ); + // integrated logout + if ( $settings->endpoint_end_session ) { + add_filter( 'allowed_redirect_hosts', array( $client_wrapper, 'update_allowed_redirect_hosts' ), 99, 1 ); + add_filter( 'logout_redirect', array( $client_wrapper, 'get_end_session_logout_redirect_url' ), 99, 1 ); + } // alter the requests according to settings add_filter( 'openid-connect-generic-alter-request', array( $client_wrapper, 'alter_request' ), 10, 3 ); @@ -181,6 +186,35 @@ class OpenID_Connect_Generic_Client_Wrapper { setcookie( $this->cookie_token_refresh_key, false, 1, COOKIEPATH, COOKIE_DOMAIN, is_ssl() ); } + function update_allowed_redirect_hosts( array $allowed ) { + $host = parse_url( $this->settings->endpoint_end_session, PHP_URL_HOST ); + if ( ! $host ) { + return false; + } + + $allowed[] = $host; + return $allowed; + } + + function get_end_session_logout_redirect_url( $redirect_url ) { + $url = $this->settings->endpoint_end_session; + $query = parse_url( $url, PHP_URL_QUERY ); + $url .= $query ? '&' : '?'; + + // prevent redirect back to the IdP when logging out in auto mode + if ( $this->settings->login_type === 'auto' && $redirect_url === 'wp-login.php?loggedout=true' ) { + $redirect_url = ''; + } + + // convert to absolute url if needed + if ( ! parse_url( $redirect_url, PHP_URL_HOST ) ) { + $redirect_url = home_url( $redirect_url ); + } + + $url .= 'post_logout_redirect_uri=' . urlencode( $redirect_url ); + return $url; + } + /** * Modify outgoing requests according to settings * diff --git a/includes/openid-connect-generic-login-form.php b/includes/openid-connect-generic-login-form.php index bd85846..18d1a4d 100644 --- a/includes/openid-connect-generic-login-form.php +++ b/includes/openid-connect-generic-login-form.php @@ -40,7 +40,8 @@ class OpenID_Connect_Generic_Login_Form { */ function handle_redirect_login_type_auto() { - if ( $GLOBALS['pagenow'] == 'wp-login.php' && $this->settings->login_type == 'auto' ) + if ( $GLOBALS['pagenow'] == 'wp-login.php' && $this->settings->login_type == 'auto' + && ( ! isset( $_GET[ 'action' ] ) || $_GET[ 'action' ] !== 'logout' ) ) { if ( ! isset( $_GET['login-error'] ) ) { wp_redirect( $this->client_wrapper->get_authentication_url() ); @@ -57,6 +58,10 @@ class OpenID_Connect_Generic_Login_Form { */ function handle_redirect_cookie() { + if ( $GLOBALS['pagenow'] == 'wp-login.php' && isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] === 'logout' ) { + return; + } + // record the URL of this page if set to redirect back to origin page if ( $this->settings->redirect_user_back ) { diff --git a/includes/openid-connect-generic-settings-page.php b/includes/openid-connect-generic-settings-page.php index 5859071..5c99116 100644 --- a/includes/openid-connect-generic-settings-page.php +++ b/includes/openid-connect-generic-settings-page.php @@ -85,6 +85,13 @@ class OpenID_Connect_Generic_Settings_Page { 'type' => 'text', 'section' => 'client_settings', ), + 'endpoint_end_session' => array( + 'title' => __( 'End Session Endpoint URL' ), + 'description' => __( 'Identify provider logout endpoint.' ), + 'example' => 'https://example.com/oauth2/logout', + 'type' => 'text', + 'section' => 'client_settings', + ), 'identity_key' => array( 'title' => __( 'Identity Key' ), 'description' => __( 'Where in the user claim array to find the user\'s identification data. Possible standard values: preferred_username, name, or sub. If you\'re having trouble, use "sub".' ),