cancel
Showing results for 
Search instead for 
Did you mean: 

SAP PI 7.4 REST Adapter Authentication

Former Member
0 Kudos

Hello,

I have a scenario where in I need to call an API from a  thirdparty site. they utilize HMAC-SHA1 security. They provided me a key and a secret. They needed a signature as well to authenticate..how can I create this signature? is that a standard functionality for the SAP REST adapter or should i need to write a JAVA code?

I need to generate a URL something similar to this to access this API, how should I configure the REST adapter? We have PI 7.4 SP12

https://api.serviceonline.com/v1/search/datafile?timestamp=1369844777731&key=fCTYXpuGkVcnDf6JLSSbtA==&signature=8qrFmQbQgILzdDeQfbJTxHXeZvE=


All security values shown here are for illustration purposes only.


Thank you.


Larry.

Accepted Solutions (1)

Accepted Solutions (1)

engswee
Active Contributor
0 Kudos

Hi Larry

AFAIK, there is no standard feature in the REST adapter to generate such a signature.

I think you'd need to generate the signature using some Java logic. Some API providers provide sample logic to access their services, like the example for Amazon below. You can probably check with the provider if they have something similar.

Java Sample Code for Calculating HMAC-SHA1 Signatures - Amazon Simple Queue Service

You can use third party libraries to do so, for example the open source library from Apache below. I haven't tried it myself, but you should be able to search for examples online.

https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/HmacUtils.ht...

Rgds

Eng Swee

vadimklimov
Active Contributor
0 Kudos

Hi Larry and Eng Swee,

As to my knowledge, currently SAP REST adapter doesn't support this kind of WS security mechanisms. On the other hand, it should be a part of Apache WSS4J (https://ws.apache.org/wss4j/), and WSS4J security handlers can be called from Axis adapter. So probably you may think of finding workaround by means of using Axis adapter instead of REST adapter?

Regards,

Vadim

engswee
Active Contributor
0 Kudos

Hi Vadim

Thanks for your input. From the description provided by Larry, it looks like the authentication is done via passing the signature in one of the query parameters. My thoughts were similar to what Indrajit has described below.

Larry, can you confirm if what is required is some form of WS security mechanism? Can you also confirm if the authentication call needs to be done before calling the API (i.e. two step call) or the authentication is done at the same time as the API call (one step call)?

Rgds

Eng Swee

vadimklimov
Active Contributor
0 Kudos

Hi Eng Swee,

You are absolutely right. I mislooked requirement to have URL amended with HMAC-SHA1 related attributes like signature, for some reason I thought Larry needs HMAC-SHA1 authentication support in relation to WSS4J standards. I totally agree with you, that if the requirement is to construct proper URL for called service and enrich it with HMAC-SHA1 compliant signature / hash value, then your and Indrajit's recommendations make sense and there is no need to over-complicate the interface by introducing full blown WSS4J support by means 3rd party libraries, REST adapter shall ideally suit these needs.

Regards,

Vadim

Answers (2)

Answers (2)

Former Member
0 Kudos

Thanks for all your input. I took time to check with the provider to see if they offer any alternatives for authentication and unfortunately they done. So I have to go with implementing the UDF to code the signature as dynamic attribute and use it in the URL pattern as Indrajit suggested. Their authentication is done at the URL when the API call is made with the payload as the request query as JSON.

Will update once I have this implemented successfully.

Thanks again for all the input.

Larry.

Former Member
0 Kudos

Hello Larry,

Do you have any update about your issues. How to solve it. Please give us some feedback.

Thank you for your support.

Many thanks & best regards,

Hubery

Former Member
0 Kudos

Hi Hubrey,

Yes, I was able to write the UDF to encrypt the signature and pass it on as a URL parameter to connect to the API services as specified in their requirements. Hope that helps. Let me know if you need any specific details. Thank you.

Best regards,

Larry.

Former Member
0 Kudos

Hello Larry,

This is very useful if you could share your solution. Currently, I communicate with third system via adapter REST, and need a signature.

Thank you for your help in advance.

Many thanks & best regards,

Hubery

Former Member
0 Kudos

Hi Hubrey,

See if the third party offers any code samples. For the site I connected, they offered code samples which I used to model my UDF. The UDF mainly took the URL and timestamp and encoded it in base64 format to get the signature. Then the signature is passed as dynamic parameter and used in the URL for connection.(as specified in my question). Hope that helps.

Regards,

Larry.

Former Member
0 Kudos

javax.crypto.spec.*

javax.crypto.Mac.*

java.security.*

org.apache.commons.codec.binary.Base64.*

You can use other libraries as well.

sample UDF:

String secretKey = "123456666";

String contentTosign = "URL" + "&timestamp=" + times + "&key=" +  gkey;

String DEFAULT_ENCODING = "UTF-8";

try {

byte[] key = Base64.decodeBase64(secretKey);

SecretKeySpec sha1Key = new SecretKeySpec(key, "HmacSHA1");

Mac mac = Mac.getInstance("HmacSHA1");

mac.init(sha1Key);

byte[] bytes = mac.doFinal(contentTosign.getBytes(DEFAULT_ENCODING));

return Base64.encodeBase64String(bytes);

}

catch (NoSuchAlgorithmException no) { return "failure";}

catch (InvalidKeyException ie) {return "failure";}

catch (UnsupportedEncodingException ue) {return "failure";}

Former Member
0 Kudos

Thank you Larry, this example is beneficial for me. I will check with third system developer.

Many thanks & Best Regards,

Hubery

Former Member
0 Kudos

Hi Larry

You have to generate the signature using java code in UDF in message mapping.

Create an inbound structure like below

<Record>

   <timestamp>

   <key>

   <signature>

In message mapping generate the values for this these fields. Then finally create the rest adapter url like below

Thanks,

Indrajit