A closer look at SOAP Sender authentication
The sender SOAP adapter authentication for SOAP sender scenarios in SAP PI is one of the most widely-discussed topics in the Process Integration SDN Forums. Recently I had a closer, technical look at this topic. Now I would like to share my most important conclusion with you. Let me follow the way I investigated it, step by step.
Let us start with how it works normally. In some systems (just like PI itself), when you configure a SOAP client, you have an option to provide a username and password to authenticate the call. These user credentials are then used every time the system tries to connect to the web service. This is the most standard approach and I would generally recommend this option every time the sender system can handle it.
But sometimes, you just do not have an option to provide the user credentials in the sender system. This is where people start to look for workarounds. There are two of them that I know of:
- Posting the SOAP call directly to Integration Engine and putting the username and the password in the SOAP call URL. This approach was described by Stefan Grube in one of his blogs here: http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/4502.
As a result, you post your SOAP calls to the following URL for SOAP calls:
- Disabling Sender SOAP authentication, as described in details by William Li in this forum message:
Frankly speaking, none of these solutions seems acceptable for me. Putting user credentials in the URL is a serious violation of the company’s security policy. As a result, I would say this is definitely not a recommended solution. And it is even worse with disabling the authentication totally, because in current PI versions you can only disable the authentication at the adapter level (not for a particular communication channel). So you immediately make your PI very vulnerable.
The question now arises: is there any other option? Initially I was thinking about using the AuthHeader property of the SOAP Header. But then I have read the following statement:
The user authentication of the SOAP adapter is not part of the SOAP adapter but of the web container of the J2EE engine.[source]
So it is not the SOAP Header where the authentication takes place, but earlier (in terms of message processing), during HTTP request processing. The user credentials are then sent along with HTTP Header parameters of the SOAP-HTTP call. You can find a quite neat description of the HTTP Header authentication here: http://www.httpwatch.com/httpgallery/authentication/
Now, it appears that the point is to add the HTTP Header parameter named “Authorization” with a value “Basic (base64-encoded username:password)”. Let me give you a small example of how it works. Assume that you have a user “someuser” with password “somepass” defined in PI, with sufficient authorization to authenticate SOAP calls. Here is how to use it in your client application. At first, you concatenate the user name and password with a colon as a separator to get: “someuser:somepass”. Then you encode “someuser:somepass” (without quotes) with base64 encoding to get c29tZXVzZXI6c29tZXBhc3M=
You might find this online tool useful for base64 encoding of a string, for testing purposes: http://www.motobit.com/util/base64-decoder-encoder.asp.
Finally you add the HTTP Header parameter:
Authorization: Basic c29tZXVzZXI6c29tZXBhc3M=
This is how this HTTP Header parameter looks \ like in the SOAP UI test tool:
Do you recognize this view? I bet you do, if you have ever used SOAP UI to test your PI scenario. It is the Aut tab where you have usually put the user name and password. And you have just accomplished an alternative configuration. Simple, isn’t it?
Finally, it is important to mention that you can use this method in any SOAP client that is capable of taking control of the HTTP header. It is not only SOAP UI where it can be used!
For instance, assuming that you have some JAVA application as a web service client, you could use the code under the link below to call the web service:
All you need to do in order to add authentication is to use the httpConn.setRequestProperty() method one more time, comparing to the example, to add the Authorization header attribute. And no longer do you need to put the username and password in the URL or think of disabling authentication for the whole SOAP adapter.
As I see it your proposal of using base64-encoding is no more secure than putting username/password directly in URL. It's just 'more' work and gives a false sense of security.
When communicating anything over HTTP all text - HTTP header and body - is transferred un-encrypted between client and host. It takes very little effort to setup a sniffing tool to intercept the communication and because everything is in clear text the system just got compromised. One could then argue that putting the username/password in base64-encoding in HTTP header Authorization is safe, but at the exact same homepage you refer to to perform the base64-encoding is also the possibility to do base64-decoding and viola - the username/password is back in clear text.
In my book that is just as unsafe as putting the username/password in URL.
The only truly secure way to communicate is by using HTTPS. We still need to be authenticated by the HTTP server, but it will only happen if the HTTPS session is created successfully and thus ensuring a secure manner of sending the username/password and the payload. Depending on how secure the communication should be, one could go for the full blown to-way trust between client and server.
If HTTPS is not an option there is the alternative solution of developing a custom LoginModule for the SOAP adapter, which is able to decrypt an encrypted username/password based on e.g. DES and adding a bit of salt to the algorithm, just to confuse a potential hacker. This, however, is still a very unsafe way of doing it, because even though it would make the decryption harder for a hacker to crack, the hacker still have the possibility to use the exact string containing the encrypted username/password to gain access to the SOAP adapter.
Thanks for your comment. Honestly, I disagree with your statements that HTTP Header authentication is no safer then including user credentials in the URL. I am not getting illusioned with the base64 encoding: it is just an encoding, not encryption, so I know it can be decoded to plain text easily. Still, you are normally not expected to have any kind of access to the header attributes of the HTTP communication between systems. Moreover, when the sender application has an option to provide user credentials for authentication explicitely, they are also sent in the HTTP header just like I described it, so there is no difference here. And for the target URL - you could possibly find it in a monitoring tool of the sender application. Where is the security in that?
>>> It takes very little effort to setup a sniffing tool to intercept the communication
How would you do that actually? It is a matter of company's network security to prevent users from capturing the network traffic. You are not really expected to have a possibility to install such a tool on the PI server or so, as a regular user. So normally you wouldn't be able to use such sniffing (or intercepting) tool.
>>> developing a custom LoginModule for the SOAP adapter
I don't think so, because of what I have mentioned in my blog: the authorization takes place before PI passes the message to the adapter, so if you do not authorize earlier, the message will throw an error and never reach your login module.
Just a small update on your questions. To a hacker there is no difference between HTTP Header or URL. If username/password is located in either of them, the hacker will find it and crack it. But for a regular user you are correct. They would probably not know what HTTP Header is and by that your username/password is 'hidden' from them.
>>>> How would you do that actually?
>>>> the authorization takes place before PI
I think you misunderstood me on this one. It is correct that _authentication_ takes place before anything reaches PI. I was not talking about an Adapter Module for a SOAP channel. The authentication is handled in the Security Provider of J2EE, where it is possible to reference a custom developed LoginModule. Have a look at this link.
I think now we have finally come to an agreement 🙂 , regarding both: regular users and a hacker. So for regular user there is no risk, because they are neither aware of this credentials being there in the HTTP header, nor able to reach it. And for hackers, it is a matter of overall network security to prevent them from doing harm.
The goal of my blog was to unreveal the technical way of how SOAP calls are authenticated by standard, and how to achieve it when it is not available explicitely, rather then to recommend it as a way to achieve additional security. Anyway, thanks for your inputs, as they are valueable for me and for others who potentially visit this blog.
Can you please let me know how can i achieve this in SAP PI ?
SOAP UI we can pass it as header but how can we pass it in SOAP receiver adapter.
Receiver SOAP adapter in PI has "native" support for web service authentication. You just put the username and password in the communication channel settings.
I tried that its no working .