php – Resposta SAML2 lida uma vez que objeto DOMDocument…

php - Resposta SAML2 lida como objeto DOMDocument...

Estou tentando usar o Azure Entra ID (macróbio Azure Active Directory) uma vez que um provedor de identidade SAML2 para um projeto Laravel 11 usando um frontend Inertia, implementando o /24Slides/laravel-saml2 pacote.

Seguindo a documentação para laravel-saml2 e referenciando o Exemplo de Power Pages Para o Azure Entra ID, consigo redirecionar para a página do IdP e fazer login, mas, depois de redirecionado de volta para meu projeto, recebo uma Serialization of 'DOMDocument' is not allowed, unless serialization methods are implemented in a subclass erro que emite de IlluminateSessionStore::save()que é chamado de IlluminateSessionMiddlewareStartSession::handleStatefulRequest().

ERROR: Serialization of 'DOMDocument' is not allowed, unless serialization methods are implemented in a subclass {"exception":"[object] (Exception(code: 0): Serialization of 'DOMDocument' is not allowed, unless serialization methods are implemented in a subclass at [[project_directory]]vendorlaravelframeworksrcIlluminateSessionStore.php:179)
[stacktrace]
#0 [internal function]: DOMNode->__sleep()
#1 [[project_directory]]vendorlaravelframeworksrcIlluminateSessionStore.php(179): serialize()
#2 [[project_directory]]vendorlaravelframeworksrcIlluminateSessionMiddlewareStartSession.php(245): IlluminateSessionStore->save()
#3 [[project_directory]]vendorlaravelframeworksrcIlluminateSessionMiddlewareStartSession.php(130): IlluminateSessionMiddlewareStartSession->saveSession()
#4 [[project_directory]]vendorlaravelframeworksrcIlluminateSessionMiddlewareStartSession.php(64): IlluminateSessionMiddlewareStartSession->handleStatefulRequest()
#5 [[project_directory]]vendorlaravelframeworksrcIlluminatePipelinePipeline.php(183): IlluminateSessionMiddlewareStartSession->handle()
#6 [[project_directory]]vendorlaravelframeworksrcIlluminateCookieMiddlewareAddQueuedCookiesToResponse.php(37): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#7 [[project_directory]]vendorlaravelframeworksrcIlluminatePipelinePipeline.php(183): IlluminateCookieMiddlewareAddQueuedCookiesToResponse->handle()
#8 [[project_directory]]vendorlaravelframeworksrcIlluminateCookieMiddlewareEncryptCookies.php(75): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#9 [[project_directory]]vendorlaravelframeworksrcIlluminatePipelinePipeline.php(183): IlluminateCookieMiddlewareEncryptCookies->handle()
#10 [[project_directory]]vendor24slideslaravel-saml2srcHttpMiddlewareResolveTenant.php(69): IlluminatePipelinePipeline->IlluminatePipeline{closure}()
#11 [[project_directory]]vendorlaravelframeworksrcIlluminatePipelinePipeline.php(183): SlidesSaml2HttpMiddlewareResolveTenant->handle()
[ etc ]

Até onde sei, o corpo da solicitação do Sua visita nos ajuda a continuar oferecendo o melhor para você! do Azure não deve resultar em um objeto DOMDocument, nem deve ter problemas com o Laravel iniciando uma sessão SAML2.

Meu bootstrapapp.php registro:

withRouting(
      web: __DIR__ . '/../routes/web.php',
      api: __DIR__ . '/../routes/api.php',
    Sua visita nos ajuda a continuar oferecendo o melhor para você!  commands: __DIR__ . '/../routes/console.php',
      health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
      $middleware->web(append: [
        AppHttpMiddlewareHandleInertiaRequests::class,
        IlluminateHttpMiddlewareAddLinkHeadersForPreloadedAssets::class,
      ]);
      $middleware->statefulApi();
      $middleware->alias([
        'abilities' => CheckAbilities::class,
        'ability' => CheckForAnyAbility::class,
      ]);
      $middleware->appendToGroup('saml', [
        IlluminateCookieMiddlewareEncryptCookies::class,
        IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
        IlluminateSessionMiddlewareStartSession::class,
      ]);
      //
    })
    ->withExceptions(function (Exceptions $exceptions) {
      $exceptions->respond(function (Response $response, Throwable $exception, Request $request) {
        if (!app()->environment(['local', 'testing']) && in_array($response->getStatusCode(), [500, 503, 404, 403])) {
          return Inertia::render('ErrorPage', ['status' => $response->getStatusCode()])
            ->toResponse($request)
            ->setStatusCode($response->getStatusCode());
        } elseif ($response->getStatusCode() === 419) {
          return back()->with([
            'message' => 'The page expired, please try again.',
          ]);
        }
        return $response;
      });
    })->create();

Meu configsaml2.php registro:

 SlidesSaml2ModelsTenant::class,
    /*
    |--------------------------------------------------------------------------
    | Use built-in routes
    |--------------------------------------------------------------------------
    |
    | If "useRoutes" set to true, the package defines five new routes:
    |
    | Method | URI                             | Name
    | -------|---------------------------------|------------------
    | POST   | {routesPrefix}/{uuid}/acs       | saml.acs
    | GET    | {routesPrefix}/{uuid}/login     | saml.login
    | GET    | {routesPrefix}/{uuid}/logout    | saml.logout
    | GET    | {routesPrefix}/{uuid}/metadata  | saml.metadata
    | GET    | {routesPrefix}/{uuid}/sls       | saml.sls
    |
    */
    'useRoutes' => true,
    'routesPrefix' => '/saml2',
    'routesMiddleware' => ['saml'],
    'retrieveParametersFromServer' => false,
    'loginRoute' => env('SAML2_LOGIN_URL'),
    'logoutRoute' => env('SAML2_LOGOUT_URL'),
    'errorRoute' => env('SAML2_ERROR_URL'),
    'strict' => true,
    'debug' => env('SAML2_DEBUG', env('APP_DEBUG', false)),
    'proxyVars' => false,
    /*
    |--------------------------------------------------------------------------
    | Service Provider configuration.
    |--------------------------------------------------------------------------
    |
    | General setting of the service provider.
    |
    */
    'sp' => [
      'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
      'x509cert' => env('SAML2_SP_CERT_x509', ''),
      'privateKey' => env('SAML2_SP_CERT_PRIVATEKEY', ''),
      'entityId' => env('SAML2_SP_ENTITYID', ''),
      'assertionConsumerService' => [
        'url' => '',
      ],
    Sua visita nos ajuda a continuar oferecendo o melhor para você!  'singleLogoutService' => [
        'url' => ''
      ],
    ],
    /*
    |--------------------------------------------------------------------------
    | OneLogin security settings.
    |--------------------------------------------------------------------------
    |
    |
    |
    */
    'security' => [
      'nameIdEncrypted' => false,
      'authnRequestsSigned' => false,
      'logoutRequestSigned' => false,
      'logoutResponseSigned' => false,
      'signMetadata' => false,
      'wantMessagesSigned' => false,
      'wantAssertionsSigned' => false,
      'wantNameIdEncrypted' => false,
      'requestedAuthnContext' => true,
    ],
    'contactPerson' => [
      'technical' => [
        'givenName' => env('SAML2_CONTACT_TECHNICAL_NAME', 'name'),
        'emailAddress' => env('SAML2_CONTACT_TECHNICAL_EMAIL', '[email protected]')
      ],
      'support' => [
        'givenName' => env('SAML2_CONTACT_SUPPORT_NAME', 'Support'),
        'emailAddress' => env('SAML2_CONTACT_SUPPORT_EMAIL', '[email protected]')
      ],
    ],
    'organization' => [
      'en-US' => [
        'name' => env('SAML2_ORGANIZATION_NAME', 'Name'),
        'displayname' => env('SAML2_ORGANIZATION_NAME', 'Display Name'),
        'url' => env('SAML2_ORGANIZATION_URL', 'http://url')
      ],
    ],
    'load_migrations' => true,
  ];

Olhar para o erro em si mostra um referência direta à mensagem que não se aplica à minha situação, a problema no github que originalmente levantou problemas com a serialização de objetos DOM em PHP, e várias pessoas com problemas semelhantes em relação Closuree.

Primeiro tentei modificar o saml middleware definido em meu bootstrapapp.phpmas remover ou substituir qualquer um dos componentes resultou em um loop de redirecionamento entre meu aplicativo e a página do IdP.

Em seguida, tentei somar uma subclasse com métodos para serializar o objeto DOMDocument, mas sem efeito:

//SUBCLASS
xmlData = $this->saveXML();
      return ['xmlData'];
    }
    public function __wakeup(): void
    {
      $this->loadXML($this->xmlData);
    }
    public static function fromUnserializable($DOMDoc){
      $serializable = new SerializableDOMDocument();
      foreach(get_object_vars($DOMDoc) as $key => $val){
        $serializable->$key = $val;
      }
      return $serializable;
    }
  }
//MODIFICATIONS TO IlluminateSessionStore::save() TO USE NEW SUBCLASS
public function save()
    {
        $this->ageFlashData();
        $this->prepareErrorBagForSerialization();
        $serializable = $this->attributes;
        if($this->attributes instanceof DOMDocument){
          $serializable = SerializableDOMDocument::fromUnserializable($this->attributes);
        }
        $this->handler->write($this->getId(), $this->prepareForStorage(
            $this->serialization === 'json' ? json_encode($this->attributes) : serialize($serializable)
        ));
        $this->started = false;
    }

Neste ponto, tenho quase certeza de que perdi alguma coisa na feição do pacote SAML2, mas não tenho certeza do que pode ser.

Deixe um comentário

Adriano Pina

Adriano Pina

Análise de Sistemas | SEO e Google Ads | Fundador da Loja Script PHP Aqui & Marca Shoslh de tecnologia

Especialista em transformar ideias em soluções digitais e acelerar o crescimento online.

Tem perguntas? Nos envia sua mensagem 24/7!

(17) 99100-0874

Endereço & Contato

Centro, Interior de São Paulo
E-mail: info@scriptphpaqui.com.br

Links Úteis
BAIXAR APP | SCRIPT PHP AQUI
Certificados
0
    0
    Seu carrinho
    Seu carrinho está vazio

    Usamos cookies para garantir que oferecemos a melhor experiência em nosso site. 

       

    X

    Clique em um de nossos representantes abaixo para conversar no WhatsApp ou envie um email para: 📧 info@scriptphpaqui.com.br

    Precisa de ajuda fale conosco?