[{ALLOW view All}]
[{ALLOW edit Markus}]
[{TableOfContents }]
!!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 different SF instances (one for each instance), because SSF application OA2CS 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.
! SuccessFactors "Manage OAuth2 Client Applications"
# button "Register Client Application"
# Application name = you can use any, but I recommend "SAP_<sysid>_<mandt>" of source SAP system
# Application URL = any, example http://SAP_<sysid>_<mandt>
# X.509 Certificate = the one created at STRUST at "SSF OAuth2 Client Identity Provider -Signature"
** export at STRUST
** double click on "SSF OAuth2 Client Identity Provider -Signature"
** double click on subject to get the certificate below
** button "Export certificate" > as Base64 > into any file
** open file and copy/paste certificate without header/footer
# Register
After that you get an "API key", which is the "OAuth 2.0 Client ID (Internal)" at OA2C_CONFIG.\\
You also need to use this one at the OAuth configuration above. Actually you can create this one first, create SAP OAuth and come back here to update certificate afterwards.
! SAP User Settings
You need to use the userId as ALIAS with 998 !
!OAuth with RFC Connections
You can use RFC for OAuth.
# create RFC of type G - "HTTP Connections to External Server"
# Host = SF server, Port = 443
# Path Prefix = keep EMPTY, if this is empty you can override it like below code
# Activate SSL, do not use a user
# 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 session (!) 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 => <Your_New_Filter>
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