Skip to content

SAML package migration #2031

Description

@kayjoosten

Remove: simplesamlphp/assert

Replace in 2 files, then composer remove simplesamlphp/assert:

File Change
library/EngineBlock/Validator/Uri.php:30 Assert::validURI($uri)filter_var($uri, FILTER_VALIDATE_URL) !== false
library/EngineBlock/Attributes/Validator/Type.php:71 Assert::validURL($url)filter_var($url, FILTER_VALIDATE_URL) !== false

Verify: unit tests for EngineBlock_Validator_Uri and EngineBlock_Attributes_Validator_Type pass unchanged.


Reduce: robrichards/xmlseclibs direct imports

XMLSecurityKey::RSA_SHA256 is used as a string constant in 5 files. Introduce one local constant and replace all references:

File Line
src/OpenConext/EngineBlock/Metadata/Coins.php 242
src/OpenConext/EngineBlock/Metadata/Entity/IdentityProvider.php 144
src/OpenConext/EngineBlock/Metadata/Entity/ServiceProvider.php 132
src/OpenConext/EngineBlock/Stepup/StepupEntityFactory.php 71, 135
src/OpenConext/EngineBlock/Metadata/X509/X509PrivateKey.php 57 (keep new XMLSecurityKey(...), only replace the constant)

robrichards/xmlseclibs stays as a dep because library/EngineBlock/Corto/Module/Bindings.php:636 calls toXmlSecurityKey() for SAML message signing and that file is out of scope. Direct imports drop from 6 files to 1. Once DocumentSigner is migrated to SigningService, X509PrivateKey::toXmlSecurityKey() also becomes dead code and can be removed.

Verify: unit + integration suite passes; phpcs clean on changed files.


Replace with stepup-saml-bundle

SAML2 container

library/EngineBlock/Saml2/Container.php is a near-identical duplicate of Surfnet\SamlBundle\SAML2\BridgeContainer in stepup-saml-bundle. Both extend SAML2\Compat\AbstractContainer, inject a PSR logger, generate IDs with openssl_random_pseudo_bytes, and throw BadMethodCallException on unsupported methods.

Action:

  1. Add surfnet/stepup-saml-bundle as a composer dependency (check version compatibility first)
  2. In library/EngineBlock/Application/Bootstrapper.php:112, replace new EngineBlock_Saml2_Container($logger) with new BridgeContainer($logger)
  3. Delete library/EngineBlock/Saml2/Container.php

Verify: full Behat default suite passes (SAML flows, logging, ID generation).

Metadata XML signing

src/OpenConext/EngineBlock/Xml/DocumentSigner.php calls SAML2\Utils::insertSignature() directly.
stepup-saml-bundle has Surfnet\SamlBundle\Service\SigningService::sign(Signable $signable, KeyPair $keyPair) which does the same call internally.

Action:

  1. Make EB's metadata XML implement Surfnet\SamlBundle\Signing\Signable (needs getRootDomElement() and getAppendBeforeNode())
  2. Inject SigningService into DocumentSigner and delegate to it
  3. Or replace DocumentSigner entirely and call SigningService directly from the metadata controller

Verify: metadata endpoint returns valid signed XML; check with xmllint or existing metadata signing tests.


Out of scope for this ticket

Too risky / separate effort — these files use simplesamlphp/saml2 and xmlseclibs heavily but are deep in the legacy Corto architecture. Reducing their deps is possible but requires refactoring 941+ lines of legacy code with significant regression risk. Track separately.

  • library/EngineBlock/Corto/Module/Bindings.php
  • library/EngineBlock/Corto/ProxyServer.php

Not suitable for stepup-saml-bundle — EB-specific business logic that does not belong in a generic reusable bundle.

  • library/EngineBlock/Saml2/NameIdResolver.php — EB-specific NameID format negotiation between SP requirements and IdP capabilities
  • library/EngineBlock/Saml2/*AnnotationDecorator.php — wraps SAML messages with EB-internal metadata (correlation IDs, keyIds, original issuers)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions