Connecting SAP SuccessFactors Using an OAuth 2.0 Client (OA2CS)#

Follow
SIMG > ABAP Platform > Application Server > Basis Services > Communication Interfaces
> OAuth 2.0 Client Implementation for SAP SuccessFactors Integration

The default implementation allows only a connection to ONE SuccessFactors instance.
Then you can use the existing objects.

This ones decribes how to create custom objects for multiple instances.

certificates / communication#

1. Configure Proxy Settings
x.SICF > F8 > Menu > Client > Proxy Settings
  • > HTTPS Protocol = <host>:<port> SKIPPED !!!
  • > Global Settings > Set Active SKIPPED !!!

OAuth configuration#

  • OAuth profile type, SM30 > OA2C_TYPES (used as filter in the BAdI)
  • OAuth profile, default "SUCCESSFACTORS", use SE80 > Create > Others > OAuth 2.0 Client Profile (t.OA2C_PROFILES, see below to add en entry in that table!)
  • Provider type, default "SuccessFactors", x.CLB2_PTYPE (SM30 > CLB2V_PTYPE)
  • Application ID, default "DEFAULT", x.CLB2_APPLI
  • Application Server Assignment, default "DEFAULT", SM34 > CLB2VC_APPLI_PLATF <= here we have the OAuth App ID and the companyId
  • Collaboration: Communication Server Settings, SM30 > CLB2V_PLATF
  • Server Communication, default "SuccessFactors", SM34 > CLB2VC_PLATF (SM30 > CLB2V_PLATF), make sure to fill also the "Authentication Methods" like USER
  • Server, default "SuccessFactors", SM34 > CLB2VC_PLATF_DEF to set server with url, provider, csfr + api version
  • Application Settings" for each instance with SM30 > CLB2V_APPL_DATA to set "Ext. Application ID" and Server
  • Parameters for each instance with SM30 > CLB2V_APPL_EXT, here we have company_id

x. OA2C_CONFIG (t.oa2c_client)

<sf_host>/oauth/token
form, header, current, SAML
www.successfactors.com
998

How to connect to multiple SF instances#

When you create a configuration with x.OA2C_CONFIG you need to enable SAML2 with the "SAML2 2.0 Disabled" button.
You can also re-do that if you use button "<TRASHBIN> SAML 2.0 Settings" and and re-enable.
First time and each time you re-enable SAML 2.0 a new certificate in STRUST at "SSF OAuth2 Client Identity Provider -Signature" is created.
You cannot have multiple STRUST certificates for SF, e.g. one for each instance, because this is hardcoded at class CL_OA2C_SAML20_METADATA->CHECK_SSF_APPLICATION_OA2C().
The trick is to use the one and only STRUST certificate in all SF instances at "Manage OAuth2 Client Applications". When you create a second OA2C_CONFIG configuration for the second instance, no new certificate at STRUST "SSF OAuth2 Client Identity Provider -Signature" is created!
This happens only if you re-enable SAML 2.0.

OAuth with RFC Connections#

You can use RFC for OAuth.
  1. create RFC of type G - "HTTP Connections to External Server"
  2. Host = SF server, Port = 443
  3. Path Prefix = keep EMPTY, if this is empty you can override it like below code
  4. Activate SSL, do not use a user
  5. button "OAuth Settings"
    • Profile = your OAuth profile name
    • Configuration = the OA2C_CONFIG configuration name
If everything is correct you can use button "Connection Test" and get a HTTP 200 response.
If not there is no proper response, you need to set a breakpoint at cl_oa2c_client_protocol_utils=>get_tokens() to capture the response to know why.
REPORT ZMDW_EC_RFC.

  DATA:
    lo_client     TYPE REF TO if_http_client,
    lv_res_data_bin TYPE xstring,
    lv_res_data_str TYPE string,
    lv_req_data_bin TYPE xstring,
    lv_req_data_str TYPE string,
    lo_conv       TYPE REF TO cl_abap_conv_in_ce.

  cl_http_client=>create_by_destination(
    EXPORTING
      "destination              = 'SF_Instance1_OAuth'
      destination              = 'SF_Instance2_OAuth'
    IMPORTING
      client                   = lo_client
    EXCEPTIONS
      argument_not_found       = 1
      destination_not_found    = 2
      destination_no_authority = 3
      plugin_not_active        = 4
      internal_error           = 5
      OTHERS                   = 6
  ).

  lo_client->request->set_method( if_http_request=>co_request_method_get ).
 "New path ->
  lo_client->request->set_header_field( name  = '~request_uri'   value = '/odata/v2/FODivision?$filter=externalCode+eq+''204''' ).  " <=========

  lo_client->send( ).
  lo_client->receive( ).

  lv_res_data_bin = lo_client->response->get_data( ).

  lo_conv = cl_abap_conv_in_ce=>create( input = lv_res_data_bin ).
  lo_conv->read( IMPORTING data = lv_res_data_str ).

  lo_client->close( ).

  cl_demo_output=>display(
    EXPORTING
      data = lv_res_data_str
      name = 'Response'
  ).

Modifications (OLD, NOT NECESSARY)#

Whenever you choose to create SAML a new STRUST is created: "SSF OAuth2 Client Identity Provider - Signature"
" Create entry with r.ZMDW_TEST, the new applic need to be assigned to the type via SM30 > CLB2V_PTYPE
FORM create_sf_application. 
  DATA: ls_app         TYPE ssfapplic, 
        ls_appt type SSFAPPLICT, 
        lv_new_app_name TYPE string. 
 
  delete from ssfapplic where applic = 'OA_CD'. 
  delete from ssfapplict where applic = 'OA_CD'. 
 
  lv_new_app_name = 'OACD'. 
  SELECT SINGLE * FROM ssfapplic INTO ls_app WHERE applic = 'OA2CS'. 
  ls_app-applic = lv_new_app_name. 
  MODIFY ssfapplic FROM  ls_app. 
  WRITE: / |modified { lv_new_app_name }, rc={ sy-subrc }|. 
 
  SELECT SINGLE * FROM SSFAPPLICT INTO ls_appt WHERE sprsl = 'E' and applic = 'OA2CS'. 
  ls_appt-applic = lv_new_app_name. 
  ls_appt-descript = |OAuth2 Client Identity Provider - { lv_new_app_name }|. 
  MODIFY SSFAPPLICT FROM  ls_appt. 
  WRITE: / |modified { lv_new_app_name }, rc={ sy-subrc }|. 
ENDFORM.
Add SFF ID specific parameters with
  • x.SSFA (t.SSFAPPLIC) or SM30 > VSSFARGS (x.SIMG > Multi Bank Connectivity Connector > Maintain SSF Application Parameters)

Note: use always same case to avoid mixing up at all artifacts: Profile, Type, Application ID, Service Provider Type, SSF ID, Server

CL_OA2C_SPECIFICS_DEFAULT
CL_OA2C_CONFIG_EXT_DEFAULT

                        (default)                 (custom)
Enh. Spot               OA2C_SPECIFICS            (not visible in OA2C_CONFIG) 
Enh. Impl.              SMI_OA2C_SPEC_SFSF        (not visible in OA2C_CONFIG)
BAdI Def                OA2C_SPECIFICS_BADI_DEF   
BAdi Impl.              SMI_OA2C_SPEC_SFSF_BIZX   => Z_SMI_OA2C_SPEC_SFSF_BIZX_CD*
Filter Value:		SUCCESSFACTORS            => Z_CONTIDEV
Implementation Class:	CL_SMI_OA2C_SPEC_SFSF	  => copied to ZCL_SMI_OA2C_SPEC_SFSF_CD
						  => exchange all references from class CL_SMI_OA2C_CONFIG_SFSF to ZCL_SMI_OA2C_CONFIG_SFSF_CD
						  => edit method IF_OA2C_SPECIFICS~GET_CONFIG_EXTENSION (replace R_CONFIG_EXTENSION name)
*SE18 > es.OA2C_SPECIFICS
  > Right-Click > Create implementation > ei.Z_SMI_OA2C_SPEC_SFSF_CD
  > bi.Z_SMI_OA2C_SPEC_SFSF_BIZX_CD
  > assign class from above and add filter
Enh. Spot               OA2C_CONFIG_EXTENSION
Enh. Impl.              SMI_OA2C_CONFIG_SFSF
BAdI Def                OA2C_CONFIG_EXTENSION_BADI_DEF
BAdi Impl.              SMI_OA2C_CONFIG_SFSF_BIZX
Filter Value:		SUCCESSFACTORS
Implementation Class:	CL_SMI_OA2C_CONFIG_SFSF => copied to ZCL_SMI_OA2C_CONFIG_SFSF_CD
						=> update attributes GC_APPLICATION and GC_SMI_SP_SFSF					
SE18 > es.OA2C_CONFIG_EXTENSION
  > Right-Click > Create implementation > ei.Z_SMI_OA2C_CONFIG_SFSF_CD
  > bi.Z_SMI_OA2C_CONFIG_SFSF_BIZX_CD
  > assign class from above and add filter	

Connection Test#

  • r.OA2C_GENERIC_ACCESS
  • r.RCLB2_DEMO_GENERIC
Choose your Service Provider Type and Application ID
Request Method: HTTP Get (GET)
Manually Entered Endpoint
  Endpoint: /odata/v2/FODivision/
  Authentication Context: User Context (USER)

Successfactors auth endpoints#

The first is not secure anymore and should not be used anymore.

/oauth/idp
	parameters: 
		client_id
		user_id
		private_key
		token_url
		use_email
		use_username  <=== true
/oauth/token
	parameters:
		company_id
		client_id
		grant_type
		assertion
		new_token	<=== true

Trace#

/usr/sap/DMD/D11/work/dev_w* (work process traces) => search for "OA2C"

Issues#

Enable SAML button#

OA2C_CONFIG > reenable/toggle "SAML 2.0 Disabled" is creating a new certificate at STRUST "SSF OAuth2 Client Identity Provider - Signature", but not if just edited- Then you need to copy the STRUST certificate to SF again!.

400 "Invalid SAML assertion. For the correct SAML assertion format.."#

  • x.OA2C_CONFIG press button "Delete SAML 2.0 Settings" Then reenable SAML 2.0 by pressing the toggle button "SAML 2.0 Disabled".
  • to use username from DMD use 998 in OA2C_CONFIG and add the userId as alias to your SAP user

401 "Client authentication failed (e.g., unknown client, no client authentication included, ...)"#

  • Wrong certificate between STRUST and SF

401 "Unable to verify the signature of the SAML assertion. Please ensure that the assertion has a signature and the key pairs match the client ID."#

  • wrong certificate in SF OAuth => use the one from STRUST "SSF OAuth2 Client Identity Provider - Signature"

401 Unable to authenticate the client (Login failed - invalid user)#

see https://me.sap.com/notes/2668018/E
  • Test: CL_OA2C_SAML20_ASSERTION->BUILD_NAME_ID() > at line 25 es_saml20_name_id-_value = sy-uname. > replace with userId
  • the SF login expects the userId though you configured and pass the username

SAML 2.0 for OAuth 2.0 client is disabled.#

  • visible at exception in CL_OA2C_CLIENT->IF_OAUTH2_CLIENT~EXECUTE_SAML20_FLOW() line 174
  • OA2C_CONFIG > reenable/toggle with "SAML 2.0 Disabled"

No implementation exists for BAdI CLB2_OAUTH2_IMPL#

  • Enhancement Implementation SMI_OAUTH2_AUTH_MAP > Add filter