Laminas Soap server security

Hi,
We are using laminas Soap for creating a soap service under laravel. I will like to know if there is any way of adding some type of security like http digest or better ws-security?

Thanks

Hey @hypemedia,

the laminas-soap package is kinda basic and does not limit you in integrating webservice security standards. If you use the soap server just bind something like an authentication decorator class to your instance.

$service = new AuthDecorator();
$service->setClassName(MySoapService::class);

$server = new Server($wsdl, $options);
$server->setObject($service);
$server->handle();

Your authentication class can look like this …

<?php

declare(strict_types=1);

namespace Marcel\Soap;

class AuthDecorator
{
    // fqcn webservice class
    protected string $className = '';
    
    // flag for a authenticated user
    protected bool $authenticated = false;

    // will be called after checking the ws-security xml
    public function __call(string $method, array $args = []): mixed
    {
        if (! $this->isAuthenticated()) {
            throw new \SoapFault(
                'Server', 
                'Authentication Error', 
                null, 
                // a data object from the classmap option to return additional xml data
            );
        }

        return call_user_func_array(
            [$this->getClassName(), $method], 
            $args
        );
    }

    // will be automatically called as soon, als a wsse header with a security node is available
    public function Security(?object $security): void
    {
        if ($security->UsernameToken->Username == 'Foo' && $security->UsernameToken->Password == 'Bar') {
            $this->setAuthenticated(true);
        }
    }

    public function getClassName(): string
    {
        return $this->className;
    }

    public function setClassName(string $className) : void
    {
        $this->className = $className;
    }

    protected function isAuthenticated(): bool
    {
        return $this->authenticated;
    }

    protected function setAuthenticated(bool $authenticated): void
    {
        $this->authenticated = $authenticated;
    }
}

The decorator checks a given wsse (webservice security) header and sets the $authenticated class member to true, als long as the given username is Foo and the given password is Bar. If you want to use another ws-security use case you have to change the logic depending on your use case.

The Security() method is alsways called first automatically. After that the __call() method is executed and calls the webservice method with the given parameters.

This would work for the following example.

<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext">
   <wsse:UsernameToken wsu:Id="mmnewmedia" 
       xmlns:wsu="http://schemas.xmlsoap.org/ws/2003/06/utility">
    <wsse:Username>Foo</wsse:Username>
    <wsse:Password Type="wsse:PasswordText">Bar</wsse:Password>
    <wsu:Created>2004-05-19T08:46:04Z</wsu:Created>
   </wsse:UsernameToken>
  </wsse:Security>
1 Like

Thanks for your answer. I will try it like that to see how it works.