xperseguers / t3ext-oidc

TYPO3 Extension oidc. This extension uses OpenID Connect to authenticate users.
https://extensions.typo3.org/extension/oidc
GNU General Public License v2.0
8 stars 28 forks source link

Logout from typo3 not calling logout of IDP #75

Open JeremyMancel opened 2 years ago

JeremyMancel commented 2 years ago

It seems that when I logout from my account on typo3 no logout calls are made to my IDP (Keycloak). Which cause that when the user is actually logged out of typo3 just by accessing the login page he gets logged in back directly, without having to enter username+password again.

(For the logout I'm using the Login Form, don't know if that's correct or not)

fkAceart commented 2 years ago

@JeremyMancel the logout Url of your openid connect is something like this url: http://my-custom-url.de/auth/realms/my-custom-idp/protocol/openid-connect/logout

You need to call this url before you invalidate the typo3 session. Therefore you need to add an eID Handler.

<?php
declare(strict_types=1);
namespace VENDOR\XYZ\Eid;

use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Core\Http\RedirectResponse;

/**
 * Class SSOLogoutService
 */
class SSOLogoutService
{

    /**
     * Global extension configuration
     *
     * @var array
     */
    protected $config;

    /**
     * Global extension configuration
     *
     * @var array
     */
    protected $myconfig;

    public function __construct()
    {
        $typo3Branch = class_exists(\TYPO3\CMS\Core\Information\Typo3Version::class)
            ? (new \TYPO3\CMS\Core\Information\Typo3Version())->getBranch()
            : TYPO3_branch;
        if (version_compare($typo3Branch, '9.0', '<')) {
            $this->config = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['oidc']);
            $this->myconfig = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['xyz']);

        } else {
            $this->config = $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['oidc'] ?? [];
            $this->myconfig = $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['xyz'] ?? [];
        }

    }

    /**
     * @return ResponseInterface
     */
    public function __invoke(): ResponseInterface
    {

        if (!empty($this->config['oidcEndpointLogout']) && !empty($this->myconfig['oidcLogoutRedirect']))
        {
            $redirect = "?redirect_uri=".urlencode($this->myconfig["oidcLogoutRedirect"]."?logintype=logout");
            return new RedirectResponse($this->config['oidcEndpointLogout'].$redirect, "302");
        }

    }
}

in your ext_localconf.php you need to add the eID Middleware. I alow added the "alwaysFetchUser" flag. So typo3 should always check if there is a valid user. But that is not required for one way syncing.

$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['logout'] = VENDRO\XYZ\Eid\SSOLogoutService::class;

//always fetch user from saml
$GLOBALS['TYPO3_CONF_VARS']['SVCONF']['auth']['setup']['FE_alwaysFetchUser'] = true;

Create or modify the ext_conf_template.txt

# cat=advanced/links/4; type=string; label= Url of the page the user gets redirect to after logout
oidcLogoutRedirect = http://localhost:2513/logout/

You need to create a logout page on the destination of the oidcLogoutRedirect value. It doesn't need any special plugins. But it must be visible without a logged in user.

You are now able to logout the user with the link /?eID=logout

xperseguers commented 1 year ago

That information may be useful in the documentation.