See how the leave request scenario can be realized in an Android App leveraging SAP NetWeaver Gateway and the OAuth 2.0 SAML Bearer Assertion Flow.
Table of Contents:
The Scenario
Configuration Guide for this scenario
To get this scenario running several configuration steps have been performed. Click on the links below to see the step-by-step descriptions for the various components involved.
Configuration Step | Tools used |
OData Service Enablement | SAP NetWeaver Gateway Transaction /IWFND/MAINT_SERVICE |
Trust Relationship to the Security Token Service (STS) | Transaction SAML2 |
Security Token Service Setup | Security Token Service Configuration |
OAuth 2.0 Client Registration | Transaction SOAUTH2 |
Resource Owner Authorizations | Transaction PFCG |
Message Flows
See the http messages the App exchanges with the Security Token Service and the SAP NetWeaver Gateway system.
1. Security Token Request
After the logon button is pressed the app will attempt to get a SAML Assertion from the Security Token Service. For this sake it’s using the WS-Trust protocol.
POST https://gatewayhe.sap.de:1443/sts/username HTTP/1.1 Content-Type: application/soap+xml; charset=utf-8 Host: gatewayhe.sap.de:1443 Content-Length: 1953 Expect: 100-continue Accept-Encoding: gzip, deflate Connection: Keep-Alive <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <s:Header> <a:Action s:mustUnderstand="1">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action> <a:MessageID>urn:uuid:021a7d99-6b05-4089-adc3-995460c97bc6</a:MessageID> <a:ReplyTo> <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> </a:ReplyTo> <a:To s:mustUnderstand="1">https://gatewayhe.sap.de:1443/sts/username</a:To> <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <u:Timestamp u:Id="_0"> <u:Created>2013-03-14T07:55:55Z</u:Created> <u:Expires>2013-03-14T08:01:55Z</u:Expires> </u:Timestamp> <o:UsernameToken u:Id="uuid-322dfa37-981c-4642-8b1a-2dd1e02d26b7-1"> <o:Username>Bob</o:Username> <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Boss123</o:Password> </o:UsernameToken> </o:Security> </s:Header> <s:Body> <trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <a:EndpointReference> <a:Address>https://gatewayhe.sap.de:1443/sap/bc/sec/oauth2/token</a:Address> </a:EndpointReference> </wsp:AppliesTo> <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType> <i:RequestDisplayToken xmlns:i="http://schemas.xmlsoap.org/ws/2005/05/identity"/> <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType> <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType> </trust:RequestSecurityToken> </s:Body> </s:Envelope>
2. Security Token Response
After a successful authentication at the Security Token Service a SAML assertion will be sent back inside a WS-Trust Security Token Response.
HTTP/1.1 200 OK Date: Thu, 14 Mar 2013 08:15:39 GMT Content-Length: 5987 Content-Type: application/soap+xml; charset=utf-8 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <s:Header> <a:Action s:mustUnderstand="1">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTRC/IssueFinal</a:Action> <a:RelatesTo>urn:uuid:021a7d99-6b05-4089-adc3-995460c97bc6</a:RelatesTo> <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <u:Timestamp u:Id="_0"> <u:Created>2013-03-14T07:57:08.633Z</u:Created> <u:Expires>2013-03-14T08:02:08.633Z</u:Expires> </u:Timestamp> </o:Security> </s:Header> <s:Body> <trust:RequestSecurityTokenResponseCollection xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512"> <trust:RequestSecurityTokenResponse> <trust:Lifetime> <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2013-03-14T07:57:08.620Z</wsu:Created> <wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2013-03-14T08:57:08.620Z</wsu:Expires> </trust:Lifetime> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing"> <wsa:Address>https://gatewayhe.sap.de:1443/sap/bc/sec/oauth2/token</wsa:Address> </wsa:EndpointReference> </wsp:AppliesTo> <trust:RequestedSecurityToken> <Assertion ID="_86845c5a-eaf8-4a75-a921-28456232cc86" IssueInstant="2013-03-14T07:57:08.622Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> <Issuer>http://gatewayhe.sap.de/sts</Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI="#_86845c5a-eaf8-4a75-a921-28456232cc86"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue>ik71oJVoUd3Se915LeTu/vIXD8A=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>SJQJ...</ds:SignatureValue> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <ds:X509Data> <ds:X509Certificate>MII... </ds:X509Data> </KeyInfo> </ds:Signature> <Subject> <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">Bob</NameID> <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <SubjectConfirmationData NotOnOrAfter="2013-03-14T08:02:08.622Z"/> </SubjectConfirmation> </Subject> <Conditions NotBefore="2013-03-14T07:57:08.620Z" NotOnOrAfter="2013-03-14T08:57:08.620Z"> <AudienceRestriction> <Audience>https://gatewayhe.sap.de:1443/sap/bc/sec/oauth2/token</Audience> </AudienceRestriction> </Conditions> <AuthnStatement AuthnInstant="2013-03-14T07:57:08.559Z"> <AuthnContext> <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef> </AuthnContext> </AuthnStatement> </Assertion> </trust:RequestedSecurityToken> <trust:RequestedAttachedReference> <SecurityTokenReference b:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:b="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"> <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_86845c5a-eaf8-4a75-a921-28456232cc86</KeyIdentifier> </SecurityTokenReference> </trust:RequestedAttachedReference> <trust:RequestedUnattachedReference> <SecurityTokenReference b:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:b="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"> <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_86845c5a-eaf8-4a75-a921-28456232cc86</KeyIdentifier> </SecurityTokenReference> </trust:RequestedUnattachedReference> <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType> <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType> <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType> </trust:RequestSecurityTokenResponse> </trust:RequestSecurityTokenResponseCollection> </s:Body> </s:Envelope>
3. Access Token Request
Having received a SAML assertion which identifies the resource owner user an OAuth 2.0 access token will be requested directly at the Gateway system where the OData service is hosted on.
POST https://gatewayhe.sap.de:1443/sap/bc/sec/oauth2/token HTTP/1.1 Authorization: Basic TE... Content-Type: application/x-www-form-urlencoded;charset=UTF-8 Host: gatewayhe.sap.de:1443 Content-Length: 4534 client_id=LEAVEAPP&scope=ZLEAVEREQUESTAPPR2_0001&grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&assertion=PEFzc2Vy...
4. Access Token Response
After successful authentication of the OAuth 2.0 client (the App in this case) and the resource owner an access token is sent back. This access token indicates that it's valid for OData service ZLEAVEREQUESTAPPR_0001 (meaning approval service in first version). The access token is now used for all proceeding requests. The initial roundtrip to the Security Token Service and the OAuth 2.0 Token Endpoint at the Gateway system is not needed anymore as long as the access token is still valid. Therefore in a productive scenario it's recommended to have a long access token validity.
HTTP/1.1 200 OK Date: Thu, 14 Mar 2013 08:15:40 GMT Server: SAP NetWeaver Application Server / ABAP 731 content-type: application/json; charset=utf-8 content-length: 142 cache-control: no-store pragma: no-cache { "access_token":"AFBWmAGzHtKjj-tfpRXSiMPdKUDqd88SFxrzwcxRGuOIdmH7","token_type":"Bearer","expires_in":"600","scope":"ZLEAVEREQUESTAPPR_0001"}
5. OData Service Request
The access token will now be used in the HTTP Bearer authorization header to access the service.
GET https://gatewayhe.sap.de:1443/sap/opu/odata/sap/zleaverequestappr/?sap-client=001 HTTP/1.1 Authorization: Bearer AFBWmAGzHtKjj-tfpRXSiMPdKUDqd88SFxrzwcxRGuOIdmH7 Host: gatewayhe.sap.de:1443
When performing change operations (HTTP POST, PUT, DELETE), prior to the OData service access an XSRF (CSRF) token needs to be fetched. This can be done using the OAuth 2.0 access token.
6. OData Service Response
HTTP/1.1 200 OK Date: Thu, 14 Mar 2013 08:15:40 GMT Server: SAP NetWeaver Application Server / ABAP 731 content-type: application/atomsvc+xml content-length: 877 dataserviceversion: 2.0 set-cookie: sap-usercontext=sap-client=001; path=/ <?xml version="1.0" encoding="utf-8"?><app:service xml:lang="en" xml:base="https://gatewayhe.sap.de:1443/sap/opu/odata/sap/zleaverequestappr/" ...
2 Comments
Former Member
Hi,
We are trying to call a few oData POST services from a non sap Web UI. Can we please get some help on this.
Thanks & Regards
Nidhi
Kishore Gokara
Hello,
If I go and check who has approved the leave request. Which user id gets updated in the table. Is it 'LEAVAPP' or Manager's user id (In this example Bob).