Technical Articles
Fetch Oauth Token in REST is now Out of The Box
Hi,
Since the REST adapter has been introduced there have been so many queries on how to fetch Oauth Token to authenticate the REST API. Our fellow SAP Community members have provided multiple solution with adapter modules and UDFs to fetch the Oauth token, but finally from SAP PO 7.5 SP13 we have out of the box functionality in adapter to do it which saves the hassle of writing a code and setting the headers with ASMA variables.
Conventional Way
- Write UDF or adapter module to fetch the token
- Pass the token in ASMA variable and use it in the HTTP Headers
- Few blogs which solved this in the the Pre-SP13 era
https://blogs.sap.com/2017/02/13/enablement-of-oauth-2.0-authorization-in-receiver-communication-channels-in-sap-pipo-using-custom-adapter-module/
https://blogs.sap.com/2017/01/23/oauth-2.0-authentication-within-a-udf-mapping-to-be-included-in-rest-receiver-channel/
Out of the Box Functionality
Finally with SP13 we have out of the box functionality to fetch the token in the adapter itself. This adds advantages like
1. avoid using external library and java classes which might need to be upgraded with time as version change occurs
2. Performance optimization
3. Easy to maintain
I will highlight some features which SAP could add still to make life easy , but first let us see how it is done.
1. General Tab -> Oauth
i) Enable Authorize with Oauth
ii) Choose the type of Flow. I am using the most common case of Bearer token Grant_type flow, we have multiple options in REST APIs for grant flow. The list can be seen and understood from – https://oauth.net/2/grant-types/
SAP has right now provided only 2 of the above grant_types.
iii) Now we need to give details further necessary to call the REST API. These details can either be HTTP Headers or Query parameter to the URL. Based on as required REST API choose the correct options.
iv) we can pass any additional parameter in the Additional Parameters, the parameter can be of following types
- Query – Parameter will be added to the URL query
- HttpHeader – Parameter will be added as HTTP header
v) I am writing this point in bold for unusual behavior of Additional Parameters. My additional parameters were supposed to go as Http Headers but it did not work so I have put it as Query parameter and it worked.
SAP claims to have resolved this with SP13 P 0028 (Note – 2782239) or from SP14. I am on Patch 27 so need to check again. I will update if I get the latest patch.
vi) One last check is the check box Use Oauth Token Caching. Now your REST API might have the token valid for certain time (say 1 hour), if you check this box the same token will be used till it expires.
To check the expiry time, try fetching token from POSTMAN, you will get response header with parameter expires_in.
Note – you do not need to maintain the expires_in parameter in SAP PO, the check box will read the expiry time from response header.
That is all , everything else remain same now your REST calls will be work fine. As mentioned in the beginning of the blog, there is one improvement which i think we can have is monitoring of this functionality.
At present the normal message logs do not display the fetched token or mentions the step of token being fetched which leaves us clueless to debug.
Hope this blog will be useful to the fellow members. also I never miss to provide references so a similar attempt has been published in the below blog
https://blogs.sap.com/2017/07/21/sap-po-rest-integration-with-salesforce-oauth/
See you soon, with next blog!
FYI ... the additional parameters are only allowed in Receiver channel and not in sender channel if we have any Rest Polling enabled.
Nice Blog Vikas !!!
Keep sharing new findings.
Very nice. I love to find technical blogs.
Michelle
Nice one vikas..
really helpful. Thanks for sharing...
Very nice !! Congratulations !!
is it possible to use this authentication with LMS (Success Factors)? I did not find a more recent blog that explained how to build in SAP PI the integration with LMS to consume ODATA services, using Oauth in a similar way to this one.
Hi Leonardo,
Thanks for your comments! not sure on Odata but if REST is enabled then above blog can do it
https://blogs.sap.com/2017/03/05/how-to-initiate-an-oauth-connection-to-successfactors-employee-central/
Hi Vikas,
I tried to use "Grant Type" and "Success Factors Type", but without success.
1) Grant Type
MP: exception caught with cause com.sap.aii.adapter.rest.ejb.common.exception.HttpCallException: HTTP OAUTH 2.0 CLIENT CREDENTIALS GRANT call to https://<servidor>:443/learning/oauth-api/rest/v1/token not successful. Error while obtaining access token - response code: 500
response:
[{"code":"500","message":"com.plateausystems.elms.framework.oauth2.api.OAuthServiceException: Failed to get Oauth2ClientSecretAuthenticationRequest form the requestBody Check the request payload and data format.\n\tat
2) Success Factors
MP: exception caught with cause com.sap.aii.adapter.rest.ejb.common.exception.HttpCallException: HTTP OAUTH 2.0 SF CLIENT CREDENTIALS GRANT call to https://<servidor>:443/learning/oauth-api/rest/v1/token not successful. Error while processing Authorization request:iaik.security.ssl.SSLException: Peer sent alert: Alert Fatal: handshake failure
Hi Leondardo,
Open your token URL in browser (may be the below is your url)
https://<servidor>:443/learning/oauth-api/rest/v1/token
Download the certificate from URL
https://www.shellhacks.com/get-ssl-certificate-from-server-site-url-export-download/
Install the certificate along with root certificate in in SAP PO (import the certificate in TrustedCA)
That is all then it should work for you
Regards,
Vikas
Now it’s working, thanks!!
But, works only with SuccessFactors Flow Type.
I opened a CSS, because there is a URL encode problem. I did a workaround:
I set module parameter EncodeURL to false and change filter parameter to encoded : “$filter=criteria/learnerID%20eq%20%27UR4K%27”
OLD URL :
<server>/learning/odatav4/searchStudent/v1/Students?$filter=criteria/learnerID eq ‘UR4K’
New URL :
<server>/learning/odatav4/searchStudent/v1/Students?$filter=criteria/learnerID%20eq%20%27UR4K%27
Now, I need set the “Scope” parameter , field “user Id”, dynamically , but I don’t know if it’s possible. I’d to get token using the real consumer user, not a hardcoded “admin” user.
I do not see the “Use OAuth token caching” option in SAP PO 7.5 SP11, could you please let me know is there an other way?
You can download the latest SWCV of SAP_BASIS from sap marketplace and import in ESR.
This will solve your problem.
https://wiki.scn.sap.com/wiki/display/XI/How+to+import+SAP+content+into+the+PI+ESR
Regards,
Vikas
Thankyou!
Hi Vikas,
Unfortunately our team is not willing to go for the basis component upgrade. What happens if the option “Use OAuth token caching” is not checked does it fetch the bearer token each time the api call is made? because i need to send the bearer token in the http header and the token expires every hour.
Regards
Sandeep A
Hi Sandeep,
If you check “Use OAuth token caching” , it will keep the token for an hour for subsequent messages.
If you dont check for every message it will fetch new token.
Regards,
Vikas
Hi both,
I figured out that not all (REST) APIs return the expires_in field. Unfortunately, it's only recommended by the protocol specifications (and not required). And the behavior of PO if this value is missing is that the token is not cached at all, despite the flagged checkbox. Instead, PO should only fetch a new token once it receives an authorization error.
Imho, this is a flaw in the implementation of the REST adapter. I hope it will be improved in future releases.
Philippe
Hi Vikas ,
i was able to fetch the taken however how do we pass the token to get the payload response do we build a second interface ?
HI Deepa,
With the out of box functionality the token gets passed to the header of request message and you get the payload response.
HI Vikas,
Env: SAP PO 7.5
How to send the username and password(vendor) in the JSON body to receive the bearer token in the receiver adapter(REST) please find the pic below:
Thanks,
Sandeep A
Hello. Sandeep
Can you resolve this ? how ?
@vikas
So would you place this in a post call where a previous get/udf call would be needed in order to obtain the jwt token ?
Thanks.
Hi Fabio,
The token is fetched from UDF/GET when this functionality was not available. Now the channel parameter will perform the GET query before any POST or PATCH to get the token and then pass the token in header along with POST
Regards,
Vikas
@Vikas kumar singh
I have a scenario where the token value is returned in the response payload of the get method. Would I be able to use this technique ? how would I configure the channel to extract the token from the "token" element in the return json payload ?
Thanks.
Also, would this work for a bearer token as well ? is there any difference ?
I would say there is no difference, this blogs token is the bearer token. So YES! 🙂
Thank you very much Vikas. One more thing...how do I say that the Token in my case will be returned in an element called "token" in the authenticantion payload ?
also, would you happen to know what the "scope" option is ?
best regards.
@Vikas could you let me know how I should day that the token will come form the "Token" element in the payload ?Also, the api I am consuming requires that I provide the token also in the endpoint. would this be possible using this configuration ?
Thanks.
Hi Fabio,
Are you able to resolve the issue related to parameter name "Token"?
Dear PI Colleagues,
I've configured almost the same type of channel (as in he image).
However, when we receive the answer it's with error, because the response is not only the access token, but a structure which contains it and it looks like : {"data":{"type":"AccessToken","attributes":{"token_type":"Bearer","expires_in":1400,"scope":"kpis","value":"**************","refresh_token":"********","refresh_token_expires_in":7200}}}
so my question is, can i configure it in the receiver channel to to extract only the "value" of the token before sending it back for the final response ?
thank you in advance,
Stefan
Hi, did you get solved this issue? I need to get all the info back from oauth.
Hi Vikas,
Nice Blog. I tried using it in one of my scenario. Where the token has to go in URL encoded format. I did attached setting in my REST adapter but it is failing. Could you please help here.
Regards,
Vaishali
Hello Vikas,
I am trying to use the below.
Grant Type: Resource Owner Password Credentials Grant
Token as: HTTP Header
Authorization Server URL: https://login.microsoftonline.com/<tenantid>/oauth2/v2.0/token where tenantid is provided as part of Open ID Connect details
Resource Owner Client ID: Application (client) ID provided as part of Open ID Connect details
Auth Server User/Password and Resource User/Password - I am using my Microsoft credentials.
The error I am getting is HTTP OAUTH 2.0 RESOURCE OWNER PASSWORD CREDENTIALS GRANT call to https://login.microsoftonline.com:443/<tenantid>/oauth2/v2.0/token not successful. Error while processing Authorization request.
Any ideas will be helpful.
Thanks,
Shaibayan
Hi Saibyan,
can you try it in postman first.
Dear Shaibayan,
were you able to solve this issue? I have the same error which did not occured in earlier calls with same configuration.
Hi Vikas,
Using postman i am able to call rest api.
While posting from postman I have used "Bearer Token" as Authorization and i have provided token.
I am fetching token from different url.
Can you help me what option shall i select in SAP PO receiver rest adapter for this.
Hi Vikas,
This is really nice blog.
I am using Postman and working fine.
Now i want to connect from SAP PI 7.5 SP 16.
We get following from customer.
So I need to choose flow as a GRANT TYPE FLOW and RESOURCE OWNER PASSWORD GRANT TYPE.
Is that correct ?
Authorization and resource user name and password should be same.
is that correct ?
Please correct my understanding.
Thanks,
Jignesh shah
8850666052
Hi Jignesh,
Sorry for late reply, i was away for sometime.
Yes your understanding is right , hope you would have already completed the scenario by now.
Regards,
Vikas Singh
Hello Jignesh shah
Now we can use OAuth 2.0 JSON Web Token profile in REST Adapter
You can see: SAP Note 2892050 - New Feature: Add Support for OAuth 2.0 JSON Web Token profile in REST Adapter.
Hi All,
How do we change the default header parameter of token? Please see question posted here
https://answers.sap.com/questions/13215314/rest-polling-oauth-20-token-change-default-header.ht
I would like to request help with this issue.
Thank you very much
PI/POSTMAN:
Hey Vikas,Can we pull all azure blob contents in a container using single rest URI call in SAP PO using REST POLLING or CPI. Let's say I have four blobs with names abc,abcd,abcdef,def. I need to pull blob contents of abc,abcd,abcdef based on some file name pattern in single REST URI call.
Hi Vikas,
I am getting error " SubCode=40104: Invalid authorization token audience". Below is the configuration of REST receiver channel.
I have not added URL pattern variables to actual REAT API call URL.
I have added only Content_Type = application/x-www-form-urlencoded to HTTP Headers tab in the receiver channel.
my data format is XML to XML only.
I have tested same with Postman. I have added resource value to Advanced Options of Authorization tab in post man. If I generate and use the token after adding resource, it is working from postman. If I generate and use the token without adding resource, from post man also it is throwing sam error " Invalid authorization token audience".
I suspect that resource is causing this error. I have added resource as HttpHeader additional parameter. It seems resource is not adding to the Authorizations while generating token from the channel.
Can you give some inputs how to pass resource to the Authorizations or HTTP Request headers?