# CakePHP4.x SAML Authentication cannot create session

**URL:** <https://discourse.cakephp.org/t/cakephp4-x-saml-authentication-cannot-create-session/9220>\
**Category:** Need Help\
**Created:** [April 9, 2021, 7:49am UTC](https://discourse.cakephp.org/t/cakephp4-x-saml-authentication-cannot-create-session/9220 "2021-04-09T07:49:40Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![rihofujino](https://avatars.discourse-cdn.com/v4/letter/r/bc79bd/32.png) [@rihofujino](https://discourse.cakephp.org/u/rihofujino)\
**Post date:** [April 9, 2021, 7:49am UTC](https://discourse.cakephp.org/t/cakephp4-x-saml-authentication-cannot-create-session/9220/1 "2021-04-09T07:49:40Z")

</div>

I would like to add Authentication by SAML for CakePHP4.x.  
I’m using Authentication plugin.  
I’m also using one login’s php library. [GitHub - onelogin/php-saml: Simple SAML toolkit for PHP](https://github.com/onelogin/php-saml)

I added custom Authenticator Class like other similar classes([authentication/authenticators.rst at master · cakephp/authentication · GitHub](https://github.com/cakephp/authentication/blob/master/docs/en/authenticators.rst)) and was able to get user info from IdP.  
However, though I’m returning user info and “Result::SUCCESS” at the end of authenticate function, Auth information cannot be created in session.

Is there any process I’m missing?

./src/Application.php

```auto
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
    $service = new AuthenticationService();
        $service->setConfig([
            'unauthenticatedRedirect' => Router::url([
                '_host' => getenv('SERVICE_HOST'),
                '_full' => true,
                '_name' => 'auth:login',
            ]),
        ]);

        $uri = $request->getUri();
        $path = $uri->getPath();

        // Load Custom Authenticator class
        if ($path === '/saml/acs') {
            $service->loadAuthenticator('SAML');
        }

        $service->loadAuthenticator('Authentication.Session');
        $service->loadAuthenticator('Authentication.Form', [
            'fields' => $fields,
            'loginUrl' => $loginApiUrl,
        ]);

    return $authenticationService;
}

```

./src/Authenticator/SAMLAuthenticator.php

```auto
class SAMLAuthenticator extends AbstractAuthenticator
{
    /**
     * @var array
     */
    protected $_defaultConfig = [];

    private $spBaseUrl;

    public function __construct()
    {
        Utils::setProxyVars(true); //https://github.com/onelogin/php-saml/issues/56

        $this->spBaseUrl = env('DEFAULT_PROTOCOL') . $_SERVER['HTTP_HOST'];
    }

    /**
     * @return OneLogin\Saml2\Auth
     */
    private function initAuthObject(int $Id)
    {
        $ssoInfo = $this->Sso->findByTeamId($Id)->first();
        $settings = [];
        $metadataInfo = $this->setMetadata($ssoInfo);
        $settingsInfo = IdPMetadataParser::injectIntoSettings($settings, $metadataInfo);

        return new Auth($settingsInfo);
    }

    private function setMetadata(object $ssoInfo): array
    {
        $metadataInfo = [
            'sp' => [
                'entityId' => $this->spBaseUrl . '/saml/metadata',
                'assertionConsumerService' => [
                    'url' => $this->spBaseUrl . '/saml/acs'
                ],
                'NameIDFormat' => $ssoInfo['nameid_format'],
            ],
            'idp' => [
                'entityId' => $ssoInfo['entity_id'],
                'singleSignOnService' => [
                    'url' => $ssoInfo['sso_url']
                ],
                'singleLogoutService' => [
                    'url' => $ssoInfo['slo_url']
                ],
                'x509cert' => $ssoInfo['certificate']
            ],
        ];

        return $metadataInfo;
    }

    /**
     * @param \Psr\Http\Message\ServerRequestInterface $request request
     * @return \Authentication\Authenticator\ResultInterface
     */
    public function authenticate(ServerRequestInterface $request): ResultInterface
    {
        $auth = $this->initAuthObject($Id);

        if (empty($_REQUEST['SAMLResponse']) || empty($_REQUEST['RelayState'])){
            return new Result(null, Result::FAILURE_CREDENTIALS_MISSING);
        }

        $auth->processResponse();
        $errors = $auth->getErrors();
        if (!empty($errors)){
            $reason = $auth->getLastErrorReason();
            Log::info('SAMLAuthenticator::authenticate:' . $reason);
            return new Result(null, Result::FAILURE_CREDENTIALS_INVALID);
        }

        $attributes = $auth->getAttributes();
        if (empty($attributes)) {
            return new Result(null, Result::FAILURE_IDENTITY_NOT_FOUND);
        }

        $user = new ArrayObject($attributes);
        return new Result($user, Result::SUCCESS);
    }
}

```

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [April 9, 2021, 2:19pm UTC](https://discourse.cakephp.org/t/cakephp4-x-saml-authentication-cannot-create-session/9220/2 "2021-04-09T14:19:54Z")

</div>

In order to persist your identity to the session, your authenticator needs to implement the `PersistenceInterface`.

---

<div class="post-metadata">

**Author:** ![alexvanniel](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/alexvanniel/32/2392_2.png) [@alexvanniel](https://discourse.cakephp.org/u/alexvanniel)\
**Post date:** [December 6, 2021, 9:03am UTC](https://discourse.cakephp.org/t/cakephp4-x-saml-authentication-cannot-create-session/9220/3 "2021-12-06T09:03:32Z")

</div>

Did you eventually solve your issues with getting SAML and the CakePHP Authentication plugin working together? We are about to start implementing and I was wondering if you mind sharing some of your experiences, issues and sollutions with me? Also, is there a specific reason you chose for Onelogin as opposed to SimpleSAMLphp?
