Desciption of the problem
We had a problem to connect to a webservice provider, which required authentication via UsernameToken. The SAP system only uses ABAP (no JAVA, no PI).
OASIS has defined the structure of the authentication information (i.e. the username and the passwort) in http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf. This authentication is part of the SOAP header.
Example for a request (taken from the PDF):
<wsse:Username> … </wsse:Username>
<wsse:Password Type=”…”> … </wsse:Password>
<wsse:Nonce EncodingType=”…”> … </wsse:Nonce>
<wsu:Created> … </wsu:Created>
The connection to the webservice has been created by generating a proxy class (using the WSDL of the service provider) and creating a logical port in the SOAMANAGER, using the same WSDL. When sending a request, the password type was missing und the service provider recected the request (even with correct username/password) because of the missing specification of the password type.
Note: OASIS defined the password type as optional, but the service provider required this attribute.
How to review the request in transaction SOAMANAGER
The XML request can be viewed in the SOAMANAGER, when the log and trace is activated:
Transaciton SOAMANAGER, tab ‘Logs and Traces’
– ‘Logs Configuration’: create a new entry with Your interface name and username, log level: all entries
– ‘Trace Configuration’: create a new entry with Your interface name and username, trace level: full trace
Restart and invoke Your interface (the webservice consumer). Back to the SOAMANGER, go to ‘Logs/Trace Viewer’; search for the last 30 minutes and select Your line (probably marked with a red icon). Then select the tab ‘Payload Trace’ and inspect the XML request. This is also useful to inspect the response for other error messages, as they are not passed to the ABAP program.
After the test, remove Your logs/trace entries.
Location of the problem
I have found the location, where SAP has introduced a ‘correction’ to compatible with .NET 3.5 in class CL_WSSE_PROCESSOR, method APPLY_USERNAME_TOKEN, where the supply of the password type for text passwords is explicitely commented (and left empty).
Later, in the transformation SEC_WSSE_USERNAMETOKEN, the password type is only written in the request, when not empty. So there is no password type information send to the service provider.
Solution of the problem
I have added an enhancement point at the end of the method APPLY_USERNAME_TOKEN to supply the password type. Please note, that I have introduced a flag, which is passed via MEMORY, on order to not interfer other interfaces, which possibly require that there is no password type. This flag has to be exported into MEMORY just before the webservice is invoked.
ENHANCEMENT 1 ZZ_CL_WSSE_PROCESSOR. “active version
* In order to not interfer with other interfaces, the password type is only supplied,
* when a special flag is passed via MEMORY:
* Code example: DATA l_flag TYPE c. EXPORT l_flag = ‘X’ TO MEMORY ID ‘APPLY_PASSWORDTYPE’.
DATA l_flag TYPE c.
IMPORT l_flag TO l_flag FROM MEMORY ID ‘APPLY_PASSWORDTYPE’.
IF ( sy-subrc = 0 ).
” remove the flag from MEMORY (use only once)
DELETE FROM MEMORY ID ‘APPLY_PASSWORDTYPE’.
IF ( l_flag = ‘X’ ) AND
( lf_is_pwd_text = ‘X’ ).
” supply the password type, like above in the comment and update the username token
ld_username_token-_a_password_type = wssec_co_pwd_text_uri.
wss_ctx->add_username_token( username_token = ld_username_token ).