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 Sua visita nos ajuda a continuar oferecendo o melhor para você! 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 IdP 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',
      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,
      ]);
      //
   Sua visita nos ajuda a continuar oferecendo o melhor para você! })
    ->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' => '',
      ],
      '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 Sua visita nos ajuda a continuar oferecendo o melhor para você! 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.

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.

Deixe um comentário

Tem perguntas? Nos envia sua mensagem 24/7!

(17) 99100-0874

Endereço & Contato

Centro, Interior de São Paulo
E-mail: [email protected]

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: 📧 [email protected]

    Precisa de ajuda fale conosco?