litesaml/schemas
Provides XML schemas for the Lite SAML ecosystem, enabling validation and tooling for SAML documents used across Lite Saml packages. Requires PHP 8.1+ and installs via Composer.
Install the Package:
composer require litesaml/schemas
Ensure your Laravel project uses PHP 8.1+ (check via php artisan --version).
First Use Case: Validate a SAML Message
use LiteSAML\Schemas\Schemas;
// Initialize the schemas provider
$schemas = new Schemas();
// Example SAML AuthnRequest XML (replace with your actual XML)
$samlXml = '<AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ...>';
// Validate against the AuthnRequest schema
$isValid = $schemas->validateSchema('AuthnRequest', $samlXml);
if (!$isValid) {
// Handle validation error (e.g., log or throw exception)
throw new \InvalidArgumentException('Invalid SAML AuthnRequest');
}
Where to Look First:
LiteSAML\Schemas\Schemas (handles schema retrieval and validation).vendor/litesaml/schemas/resources/schemas/ (e.g., AuthnRequest.xsd).Integrate validation into a Laravel controller handling SAML requests:
use Illuminate\Http\Request;
use LiteSAML\Schemas\Schemas;
class SamlController extends Controller
{
protected $schemas;
public function __construct(Schemas $schemas)
{
$this->schemas = $schemas;
}
public function handleAuthnRequest(Request $request)
{
$samlXml = $request->input('SAMLRequest'); // Base64-decoded XML
$isValid = $this->schemas->validateSchema('AuthnRequest', $samlXml);
if (!$isValid) {
return response()->json(['error' => 'Invalid SAML AuthnRequest'], 400);
}
// Proceed with SAML processing
}
}
Register the Schemas class as a Laravel service provider for dependency injection:
// app/Providers/AppServiceProvider.php
use Illuminate\Support\ServiceProvider;
use LiteSAML\Schemas\Schemas;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Schemas::class, function ($app) {
return new Schemas();
});
}
}
Now inject Schemas into any class via constructor injection.
Create middleware to validate SAML messages before processing:
// app/Http/Middleware/ValidateSamlSchema.php
use Closure;
use LiteSAML\Schemas\Schemas;
class ValidateSamlSchema
{
protected $schemas;
public function __construct(Schemas $schemas)
{
$this->schemas = $schemas;
}
public function handle($request, Closure $next)
{
if ($request->has('SAMLRequest')) {
$samlXml = $request->input('SAMLRequest');
$schemaName = $this->determineSchemaName($request); // Logic to pick schema (e.g., 'AuthnRequest')
if (!$this->schemas->validateSchema($schemaName, $samlXml)) {
return response()->json(['error' => 'Invalid SAML schema'], 400);
}
}
return $next($request);
}
}
Register the middleware in app/Http/Kernel.php.
Load schemas dynamically based on runtime conditions (e.g., SAML version):
$schemaName = $request->input('SAMLVersion') === '2.0' ? 'AuthnRequest' : 'AuthnRequest11';
$isValid = $schemas->validateSchema($schemaName, $samlXml);
Use Laravel’s testing tools to validate SAML schemas:
// tests/Feature/SamlValidationTest.php
use Tests\TestCase;
use LiteSAML\Schemas\Schemas;
class SamlValidationTest extends TestCase
{
public function testValidAuthnRequest()
{
$schemas = new Schemas();
$validXml = file_get_contents(__DIR__ . '/data/valid-authnrequest.xml');
$this->assertTrue($schemas->validateSchema('AuthnRequest', $validXml));
}
public function testInvalidAuthnRequest()
{
$schemas = new Schemas();
$invalidXml = file_get_contents(__DIR__ . '/data/invalid-authnrequest.xml');
$this->assertFalse($schemas->validateSchema('AuthnRequest', $invalidXml));
}
}
If using litesaml/core, combine schema validation with SAML processing:
use LiteSAML\Schemas\Schemas;
use LiteSAML\AuthnRequest;
$schemas = new Schemas();
$samlXml = $request->input('SAMLRequest');
// Validate schema first
if (!$schemas->validateSchema('AuthnRequest', $samlXml)) {
abort(400, 'Invalid SAML AuthnRequest');
}
// Process with LiteSAML
$authnRequest = AuthnRequest::fromString($samlXml);
Empty XML Handling:
if (empty($samlXml)) {
throw new \InvalidArgumentException('SAML XML cannot be empty');
}
Schema Name Mismatches:
AuthnRequest vs. AuthnRequest11) will fail silently. Use exact names from the LiteSAML Cookbook.XML Encoding Issues:
$samlXml = base64_decode($request->input('SAMLRequest'));
Performance with Large XML:
SimpleXML with libxml_disable_entity_loader).$schema = Cache::remember("schema_{$schemaName}", 3600, function () use ($schemas, $schemaName) {
return $schemas->getSchema($schemaName);
});
PHP Extensions:
ext-dom and ext-simplexml are enabled (required for XML validation).Enable XML Error Reporting:
libxml_use_internal_errors(true);
$schemas->validateSchema('AuthnRequest', $samlXml);
$errors = libxml_get_errors();
foreach ($errors as $error) {
error_log("XML Error: {$error->message} (Line {$error->line})");
}
libxml_clear_errors();
Log Schema Validation Failures:
try {
$isValid = $schemas->validateSchema('AuthnRequest', $samlXml);
} catch (\Exception $e) {
\Log::error("SAML Validation Failed", [
'schema' => 'AuthnRequest',
'error' => $e->getMessage(),
'xml_sample' => substr($samlXml, 0, 500) // Log first 500 chars
]);
}
Validate Against Test Vectors: Use OASIS SAML Test Vectors to test edge cases.
Schema Path Customization: Override the default schema directory (e.g., for custom schemas):
$schemas = new Schemas();
$schemas->setSchemaDirectory(__DIR__ . '/custom-schemas');
Laravel Caching: Cache schema objects to avoid repeated file reads:
$schema = Cache::remember("schema_{$schemaName}", now()->addHours(1), function () use ($schemas, $schemaName) {
return $schemas->getSchema($schemaName);
});
SAML Version Handling:
How can I help you explore Laravel packages today?