composer require authentin/eusig-bundle symfony/http-client nyholm/psr7
config/packages/eusig.yaml:
eusig:
dss:
base_url: '%env(DSS_BASE_URL)%' # e.g., http://localhost:8080/services/rest
docker run -d -p 8080:8080 ghcr.io/authentin/dss:latest
SignerInterface into a controller and use:
$signedPdf = $signer->sign(
Document::fromLocalFile('/path/to/file.pdf'),
new SignatureParameters(signatureLevel: SignatureLevel::PAdES_BASELINE_B)
);
PDF Signing Pipeline
// Controller
public function signPdf(SignerInterface $signer, string $filePath): Response
{
$document = Document::fromLocalFile($filePath);
$signed = $signer->sign($document, new SignatureParameters());
return new Response($signed->content, 200, ['Content-Type' => 'application/pdf']);
}
Validation Middleware
// src/Middleware/ValidateSignature.php
public function handle(Request $request, Closure $next)
{
if ($request->hasFile('signed_pdf')) {
$validator = $this->container->get(ValidatorInterface::class);
$result = $validator->validateSignature(
Document::fromStream($request->file('signed_pdf')->getRealPath())
);
if (!$result->valid) {
throw new \RuntimeException('Invalid signature');
}
}
return $next($request);
}
Batch Processing
// Command
protected function execute(InputInterface $input, OutputInterface $output): int
{
$signer = $this->container->get(SignerInterface::class);
foreach ($this->getFilesToSign() as $file) {
$signed = $signer->sign(Document::fromLocalFile($file), $this->params);
file_put_contents($file . '.signed', $signed->content);
}
return Command::SUCCESS;
}
Document::fromStream() for uploaded files:
$document = Document::fromStream($request->file('document')->getRealPath());
EusigException:
try {
$result = $validator->validateSignature($document);
} catch (EusigException $e) {
$this->addFlash('error', $e->getMessage());
}
eusig.yaml for project-specific defaults:
eusig:
defaults:
signature_level: PAdES_BASELINE_LT # Override globally
DSS Connection Issues
ClientException with "Connection refused".docker ps) and base_url is correct.symfony/http-client's debug mode:
$client = new HttpClient(['debug' => true]);
$this->container->set(SigningClientInterface::class, new DSSClient($client, $config));
PKCS12 Token Errors
TokenException with "Invalid keystore".PKCS12_PATH points to a valid .p12 file.PKCS12_PASSWORD matches the keystore password.openssl pkcs12 -info -in /path/to/keystore.p12
Signature Level Mismatch
signature_level in SignatureParameters matches the DSS server's capabilities (check DSS logs or documentation).eusig.yaml:
eusig:
dss:
debug: true
Document::toString() to verify content before signing:
$doc = Document::fromLocalFile('/path/to/file.pdf');
file_put_contents('debug.pdf', $doc->content); // Inspect manually
$report = $validator->validateSignature($document);
dump($report->details); // Array of signature-specific data
Custom Token Backend
TokenInterface for HSM/remote providers:
class RemoteToken implements TokenInterface {
public function sign(Document $document, SignatureParameters $params): Document {
// Call remote API
}
}
authentin.eusig.token tag.Signature Policy Overrides
SignatureParameters for project-specific rules:
class CustomParameters extends SignatureParameters {
public function __construct() {
parent::__construct(
signatureLevel: SignatureLevel::PAdES_BASELINE_LT,
customPolicy: 'MyCompanyPolicy'
);
}
}
Event Listeners
eusig.signature.created events for post-signing actions:
# config/services.yaml
App\EventListener\SignatureLogger:
tags:
- { name: kernel.event_listener, event: eusig.signature.created, method: onSignatureCreated }
SHA256 digest). Override only if required.%env() for sensitive data (e.g., PKCS12_PASSWORD).SigningClientInterface.How can I help you explore Laravel packages today?