cancel
Showing results for 
Search instead for 
Did you mean: 

External Web Service Requires - WS-Security Header (calling from ABAP)

former_member199351
Active Participant
0 Kudos

Hello,

I have created the proxy for external Web Servcie and ABAP program to trigger it This service requires header authentication, without which I get the following error:

CODE:SoapFaultCode:1

ERRORTEXT: Security Data : No WS-Security Header

I have found a thread that deals with such issue:

In that thread Thomas Jung gives example of the program on how to create service header. However, the following code does not work for me:

concatenate

'<Header>'

'<Security mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">'

'<UsernameToken Id="uuid-e55489fa6444-1">'

'<Username>User123</Username>'

'<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wssusername-token-profile-1.0#PasswordText">Pass123</Password>'

'</UsernameToken>'

'</Security>'

'</Header>' into l_string.

** convert to xstring*

l_xstring = cl_proxy_service=>cstring2xstring( l_string ).

if not l_string is initial.

** create iXML DOM document from XML xstring*

call function 'SDIXML_XML_TO_DOM'

exporting

xml = l_xstring

importing

document = xml_document

exceptions

invalid_input = 1

others = 2.

if sy-subrc = 0 and not xml_document is initial.

xml_root = xml_document->get_root_element( ).

xml_element ?= xml_root->get_first_child( ).

** add header element by element to SOAP header*

while not xml_element is initial.

name = xml_element->get_name( ).

namespace = xml_element->get_namespace_uri( ).

ws_header->set_request_header(

name = name

namespace = namespace

dom = xml_element ).

xml_element ?= xml_element->get_next( ).

endwhile.

endif.

endif.

The while loop stops because xml_element ?= xml_element->get_next( ) does not retrieve the next element. And even the first element is retrieved only partially, just its name.

Does anyone know why this code does not work? Is there any other way to pass WS-Security Header.

Thanks,

Alex

Accepted Solutions (0)

Answers (5)

Answers (5)

former_member199351
Active Participant
0 Kudos

Hi Abhishek,

Thanks for your help. I saw this note before, but it was not the issue.

I was able to fix the issue last night, it was caused by preparing WS header incorrectly. Originally, I did not use wsse prefix, and this was issue number 1. Once I added the prefix, I thought that the following code is incorrect because it was only retreiving 1 elements - UsernameToken.

xml_root = xml_document->get_root_element( ).

xml_element ?= xml_root->get_first_child( ).

* add header element by element to SOAP header

while not xml_element is initial.

name = xml_element->get_name( ).

namespace = xml_element->get_namespace_uri( ).

ws_header->set_request_header(

name = name

namespace = namespace

dom = xml_element ).

xml_element ?= xml_element->get_next( ).

endwhile.

So, I added to logic to get and then set all childeren, and this was the mistake. This is what caused "XML Parse Error". UsernameToken had already all info with user name and password. Once I removed the extra logic to get all 4 elements, the client proxy began working.

Regards,

Alex

surendra_battula
Participant
0 Kudos

Hi Alex

I am actually trying the same scenario where xml_element ?= xml_element->get_next( )

is not looping for the next value. how did u fix it as do I need to add get_first_child in the loop and ignore the get_next in the loop.

thanks

sbattula

Former Member
0 Kudos

Hi Sbattula,

In this example:

<Header>'

'<Security mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">'

'<UsernameToken Id="uuid-e55489fa6444-1">'

'<Username>User123</Username>'

'<Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wssusername-token-profile-1.0#PasswordText">Pass123</Password>'

'</UsernameToken>'

'</Security>'

'</Header>' into l_string.

You don't need to loop in for the next values (Usernametoken, Username, Password). Those values are inside of Security. Therefore, if in the first interaction the while loop finds the tag Security that will be enough.

Could you tell me how did you configure the logical port? I'm not sure if I did mine right.

Thanks,

Fabián



surendra_battula
Participant
0 Kudos

Once  I have created a consumer proxy can see a ICON (start SOAMANAGER)

1) click it  and select  the service and click create and

2) uploaded the wsdl service from the file click next

3) fill the username and password click next

4) for the rest of the steps I kept clicking on next until I finish.

I still cant figure it out whats wrong on My side as

header information is as below

   <soapenv:Header>

        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

            <wsse:UsernameToken>

                <wsse:Username>' user '</wsse:Username>

                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">' password '</wsse:Password>

            </wsse:UsernameToken>

        </wsse:Security>

but it works good when I test it in SOAP UI application.

but from the report it gives me errors "system fault code".

I am tired of this. as u have said it will have all information from security. so in that case it only loops once and exits as user token is not a adjacent node and get next fails.

the other thing is do we need to pass field name and value to control parameters in the input.

suggest if any ideas.

Former Member
0 Kudos

Hi Sbattula,


Thanks for the information about creating the logical port. I had to created manually because there is something wrong with SOAMANAGER when I try to use the WSDL.


What I found out yesterday is that I have an error with the schema used to envelope my XML message. I activate the Payload trace through SOAMANAGER and I checked the original payload message. The payload message is using the following schema:


<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">


The webservice I'm trying to consume uses this schema:


<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">


I need to change the schema in order to get my proxy working. By the way, here is my security header data:


<wsa:MessageID xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">uuid:005056a2-201c-1ee6-9a97-f0d8eed6a5af</wsa:MessageID>

  <wsa:Security xmlns:wsa="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">

  <wsa:UsernameToken Id="UsernameToken-EB83C94253773681E5XXXXXXXX">

  <wsa:Username>usrXXXXXX</wsa:Username>

  <wsa:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">********</wsa:Password>

  </wsa:UsernameToken>

  </wsa:Security>


As you can see, the loop to insert the security is working. Even if only gets the first tag.


Hope this helps you.



surendra_battula
Participant
0 Kudos

Hi Fabian

thanks for the reply

I Have did some trace and found this as below image. as my error is soap fault code 01

the schema mentioned

xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"

but  my wsdl code definition looks like this from definition

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:xxxx" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" name="customprocurement" targetNamespace="urn:xxxx">



do u have any idea where I need to change the definition of schema or does it look right.


Former Member
0 Kudos

Hi Sbattula,


What we did today in the office was to change some configuration in the logical port of the service consumer. Changing the transport binding type from SOAP 1.1 to SOAP 1.2 worked for us. It changed our schema to <soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">.


I actually don't know much about changing the wsdl code definition.


Good luck.

surendra_battula
Participant
0 Kudos

HI Fabian

thanks man

It worked finally this morning and what u told is right

the security info have all the data of the username and password.

thanks

sbattula

surendra_battula
Participant
0 Kudos

Hi Fabian

please see my discussion where I have raised my issue first.

as I have answered how I got a solution.

Regards

sbattula

former_member199351
Active Participant
0 Kudos

The info below is from trace file:

XRFC> <

XRFC> <

XRFC> INFO 09:40:16: SOAP SESSION Protocol CL_SOAP_SESSION_PROTOCOL <

XRFC> ->IF_SOAP_PROTOCOL~PRE_PROCESS() SOAP Session Protocol <

XRFC> preprocessed <

XRFC> <

XRFC> INFO 09:40:16: SOAP Transport Binding CL_SOAP_HTTP_TPBND_ROOT <

XRFC> ->IF_SOAP_TRANSPORT_BINDING~SEND() Try to send message ( DEST = <

XRFC> CCTEST_AUC ,PATH = ,URL = ,SOAP Action = "runTransaction" ) <

XRFC> <

XRFC> INFO 09:40:16: SOAP Transport Binding CL_SOAP_HTTP_TPBND_ROOT <

XRFC> ->IF_SOAP_TRANSPORT_BINDING~SEND() Message sent <

XRFC> <

XRFC> INFO 09:40:16: SOAP Transport binding CL_SOAP_HTTP_TPBND_ROOT <

XRFC> ->IF_SOAP_TRANSPORT_BINDING~RECEIVE() Try to receive message <

XRFC> <

XRFC> INFO 09:40:16: SOAP HTTP Binding CL_SOAP_HTTP_TPBND_ROOT->HANDLE <

XRFC> STATUSCODE() Received return code 500 ( Internal Server Error ) <

XRFC> <

XRFC> ERROR 09:40:16: SOAP Message CL_SOAP_MESSAGE->IF_SOAP_MESSAGE <

XRFC> PART~INITFOR_DESERIALIZE() SOAP Fault Exception caught: :

XML <

XRFC> parse error.

<

XRFC> <

I highlighted in bold where the error takes place. Did anyone experienced this?

Thanks,

Alex

Former Member
0 Kudos

Hi for

this error CL_SOAP_HTTP_TPBND_ROOT

Check Note 921347

Regards

Abhishek

Former Member
0 Kudos

Hi for

this error CL_SOAP_HTTP_TPBND_ROOT

Check Note 921347

Regards

Abhishek

Former Member
0 Kudos

Hi for

this error CL_SOAP_HTTP_TPBND_ROOT

Check Note 921347

Regards

Abhishek

Former Member
0 Kudos

Internet problem

My message get posted here 3 times

Regards

former_member199351
Active Participant
0 Kudos

A bit more info.

If I do not pass UsernameToken element, I get the error that UsernameToken is missing, but once it is passed, I can XML Parse Error. It looks like it can not interpret UsernameToken for some reason.

Thanks,

Alex

former_member199351
Active Participant
0 Kudos

I was finally able to get all 4 elements Security, UsernameToken, Username and Password in WS_HEADER. Below is modified while loop logic:

while not xml_element is initial.

clear: name, namespace.

name = xml_element->get_name( ).

namespace = xml_element->get_namespace_uri( ).

ws_header->set_request_header(

name = name

namespace = namespace

dom = xml_element ).

if name = 'Username'.

xml_element ?= xml_element->get_next( ).

elseif name = 'Password'.

exit.

else.

xml_element ?= xml_element->get_first_child( ).

endif.

endwhile.

I should not have called xml_element ?= xml_element->get_next( ). always within the while loop since UsernameToken also has children. I hardcoded the names in if statement for now, but this can be derived dynamically.

Unfortunately, this was not the end of the issues. Now when I call the proxy, I get the following error:

CODE: SoapFaultCode:4

ERRORTEXT: #XML parse error.#

Any idea why? The system is NW 7.0 SP12.

Thanks,

Alex

former_member199351
Active Participant
0 Kudos

I have done the following change to XML string:

concatenate

'<SOAP:Header>'

'<wsse:Security mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">'

'<wsse:UsernameToken Id="uuid-e55489fa6444-1">'

'<wsse:Username>User123</wsse:Username>'

'<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wssusername-token-profile-1.0#PasswordText">Pass123</wsse:Password>'

'</wsse:UsernameToken>'

'</wsse:Security>'

'</SOAP:Header>' into l_string.

Adding wsse allowed to retrieve and set the first element "Security" to header. But all following elements were ignored. The logic xml_element ?= xml_element->get_next( ) in while loop returns null.

Any idea?

Thanks,

Alex