Skip to end of metadata
Go to start of metadata

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
OAuth 2.0 enabling of the approval service, OAuth 2.0 Scope creation and assignment

SAP NetWeaver Gateway Transaction /IWFND/MAINT_SERVICE

Trust Relationship to the Security Token Service (STS)
Configure the Gateway System to trust SAML Bearer assertions issued by the STS

Transaction SAML2

Security Token Service Setup
Registration of the SAP NW Gateway System in order for the STS to be able to issue SAML Assertions for it

Security Token Service Configuration

OAuth 2.0 Client Registration
Registration of the OAuth 2.0 client “LEAVEAPP”, which is the client the Android App is using to make calls on behalf of the resource owner user

Transaction SOAUTH2

Resource Owner Authorizations
Assignment of authority object S_SCOPE next to the manager and employee users' usual permissions

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

  1. 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

  2. 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).