# Laminas Soap server security

**URL:** <https://discourse.laminas.dev/t/laminas-soap-server-security/3662>\
**Category:** API Tools\
**Created:** [April 7, 2024, 1:36pm UTC](https://discourse.laminas.dev/t/laminas-soap-server-security/3662 "2024-04-07T13:36:43Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![hypemedia](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/hypemedia/32/456_2.png) [@hypemedia](https://discourse.laminas.dev/u/hypemedia)\
**Post date:** [April 7, 2024, 1:36pm UTC](https://discourse.laminas.dev/t/laminas-soap-server-security/3662/1 "2024-04-07T13:36:43Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![ezkimo](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/ezkimo/32/781_2.png) [@ezkimo](https://discourse.laminas.dev/u/ezkimo)\
**Post date:** [April 8, 2024, 11:16am UTC](https://discourse.laminas.dev/t/laminas-soap-server-security/3662/2 "2024-04-08T11:16:19Z")

</div>

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.

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

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

```

Your authentication class can look like this …

```auto
<?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.

```auto
<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>

```

---

<div class="post-metadata">

**Author:** ![hypemedia](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/hypemedia/32/456_2.png) [@hypemedia](https://discourse.laminas.dev/u/hypemedia)\
**Post date:** [April 9, 2024, 7:26am UTC](https://discourse.laminas.dev/t/laminas-soap-server-security/3662/3 "2024-04-09T07:26:40Z")

</div>

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