diff --git a/inc/admin/namespace.php b/inc/admin/namespace.php index 2c05d6a..0f0eadc 100644 --- a/inc/admin/namespace.php +++ b/inc/admin/namespace.php @@ -73,16 +73,10 @@ function get_config() { return []; } - $settings['sp'] = [ - 'entityId' => $sp_home_url, - 'assertionConsumerService' => [ - 'url' => $sp_base_url . 'verify', - ], - 'singleLogoutService' => [ - 'url' => $sp_base_url . 'sls', - ], - 'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', - ]; + $settings['sp']['entityId'] = $sp_home_url; + $settings['sp']['assertionConsumerService'] = [ 'url' => $sp_base_url . 'verify' ]; + $settings['sp']['singleLogoutService'] = [ 'url' => $sp_base_url . 'sls' ]; + $settings['sp']['NameIDFormat'] = 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'; return $settings; } diff --git a/inc/namespace.php b/inc/namespace.php index 43f9a90..3e04058 100644 --- a/inc/namespace.php +++ b/inc/namespace.php @@ -41,13 +41,15 @@ function bootstrap() { add_action( 'template_redirect', __NAMESPACE__ . '\\endpoint', 9 ); add_action( 'login_message', __NAMESPACE__ . '\\login_form_link' ); add_action( 'wp_authenticate', __NAMESPACE__ . '\\authenticate_with_sso' ); - add_action( 'wp_logout', __NAMESPACE__ . '\\go_home' ); + add_action( 'wp_logout', __NAMESPACE__ . '\\logout' ); add_action( 'wpsimplesaml_action_login', __NAMESPACE__ . '\\cross_site_sso' ); add_action( 'wpsimplesaml_action_verify', __NAMESPACE__ . '\\cross_site_sso' ); + add_action( 'wpsimplesaml_action_sls', __NAMESPACE__ . '\\cross_site_sso' ); add_action( 'wpsimplesaml_action_login', __NAMESPACE__ . '\\action_login' ); add_action( 'wpsimplesaml_action_verify', __NAMESPACE__ . '\\action_verify' ); + add_action( 'wpsimplesaml_action_sls', __NAMESPACE__ . '\\action_sls' ); add_action( 'wpsimplesaml_action_metadata', __NAMESPACE__ . '\\action_metadata' ); add_action( 'wpsimplesaml_user_created', __NAMESPACE__ . '\\map_user_roles', 10, 2 ); @@ -273,6 +275,43 @@ function action_verify() { } } +/** + * Handle sso/sls endpoint. + * + * @action wpsimplesaml_action_sls + */ +function action_sls() { + $saml = instance(); + + try { + /* + * If it's logout request, we just clear the user session. The user will be redirected to + * the IdP by the php-saml. + * If it's logout responce, the IdP has ended user's session, php-saml will not do + * anything else, so we will redirect at the end. + */ + $saml->processSLO( false, null, true, __NAMESPACE__ . '\signout' ); + } catch ( \Exception $e ) { + $errors = $e->getMessage(); + } + + if ( $errors ) { + /* translators: %s = error message */ + wp_die( sprintf( esc_html__( 'Error: Could not parse the logout response, please forward this error to your administrator: "%s"', 'wp-simple-saml' ), esc_html( $errors ) ) ); + } + + if ( ! empty( $saml->getErrors() ) ) { + $errors = implode( ', ', $saml->getErrors() ); + + /* translators: %s = error message */ + wp_die( sprintf( esc_html__( 'Error: Could not parse the logout response, please forward this error to your administrator: "%s"', 'wp-simple-saml' ), esc_html( $errors ) ) ); + } + + $redirect_url = get_redirection_url(); + wp_safe_redirect( $redirect_url ); + exit; +} + /** * Output metadata of SP * @@ -533,6 +572,27 @@ function signon( $user ) { wp_set_auth_cookie( $user->ID, true, is_ssl() ); } +/** + * Sign out the user, delete session and auth cookie. + */ +function signout() { + wp_destroy_current_session(); + wp_clear_auth_cookie(); +} + +/** + * Send LogoutRequest to IdP when user logs out. + */ +function logout() { + // Bail if no SAML2_Auth instance is available, mainly if no configuration was found + if ( ! instance() ) { + return; + } + + $redirect_url = get_redirection_url(); + instance()->logout( $redirect_url ); +} + /** * Forward IdP response to another site *