You were almost spot on with the first attempt, you just have to pass the SOAP::Header to the method call and SOAP::Lite will Do The Right Thing, I'd also suggest setting autotype off on the soap client as that suppresses the typing on the elements which might confuse some toolkits:
use SOAP::Lite +trace;
$uri = 'urn:Foo';
$proxy = 'http://localhost/';
$username = 'username';
$password = 'password';
my $client = SOAP::Lite
->readable(1)
->uri($uri)
->proxy($proxy);
$client->autotype(0);
my $Username = SOAP::Header->name('Username' => $username);
my $Password = SOAP::Header->name('Password' => $password);
my $UsernameToken = SOAP::Header->name('UsernameToken')
->value(\SOAP::Header->value($Username, $Password));
my $security = SOAP::Header->name('Security')
->attr({'xmlns' => 'http://schemas.xmlsoap.org/ws/2002/xx/
+secext'})
->value(\$UsernameToken);
$elem1 = SOAP::Data->name('ELEM1' => "value1");
$elem2 = SOAP::Data->name('ELEM2' => "value2");
$response = $client->mymethod($elem1,$elem2, $security);
This produces (for me anyway, let's all wait for an
Anonymous Monk to turn up
saying I'm lying in a bit:)
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/xx/secext">
<UsernameToken>
<Username>username</Username>
<Password>password</Password>
</UsernameToken>
</Security>
</soap:Header>
<soap:Body>
<mymethod xmlns="urn:Foo">
<ELEM1>value1</ELEM1>
<ELEM2>value2</ELEM2>
</mymethod>
</soap:Body>
</soap:Envelope>
/J\