Inhaltsverzeichnis
- Connecting SAP SuccessFactors Using an OAuth 2.0 Client (OA2CS)
- certificates / communication
- How to connect to multiple SF instances
- OAuth configuration
- Transaction OA2C_CONFIG
- OAuth
- Create BAdIs, copy/adjust classes
- SuccessFactors "Manage OAuth2 Client Applications"
- OAuth with RFC Connections
- Modifications (OLD, NOT NECESSARY)
- Connection Test
- SF Token lifetime
- Successfactors auth endpoints
- Trace
- Issues
- Enable SAML button
- 400 "Invalid SAML assertion. For the correct SAML assertion format.."
- 401 "Client authentication failed (e.g., unknown client, no client authentication included, ...)"
- 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."
- 401 Unable to authenticate the client (Login failed - invalid user)
- SAML 2.0 for OAuth 2.0 client is disabled.
- 400 - Parameter "company_id" is required in the OAuth request
- No implementation exists for BAdI CLB2_OAUTH2_IMPL
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 Settingsx.SICF > F8 > Menu > Client > Proxy Settings
- > HTTPS Protocol = <host>:<port> SKIPPED !!!
- > Global Settings > Set Active SKIPPED !!!
How to connect to multiple SF instances#
You can use below default configuration if you want to connect your SAP system to ONE SF instance only, otherwise you need to copy/adjust everythingWhen 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.
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, you can search in SE80 with "_QS Development Object")
- Provider type, default "SuccessFactors", x.CLB2_PTYPE (SM30 > CLB2V_PTYPE)
- Application ID, default "DEFAULT", x.CLB2_APPLI
- API Method, default GENERIC, SM30 > CLB2V_PTYPE_METH (copy default)
- API Method Version, default V1 and CL_CLB2_METHOD, SM30 > CLB2V_PTYPE_VERS (copy default)
- Server, default "SuccessFactors", SM34 > CLB2VC_PLATF_DEF to set server with url, provider, csfr + api version
- Collaboration: Communication Server Settings, SM30 > CLB2V_PLATF
- Application Server Assignment, default "DEFAULT", SM34 > CLB2VC_APPLI_PLATF <= here we have the OAuth App ID and the companyId
- Server Communication, default "SuccessFactors", SM34 > CLB2VC_PLATF, make sure to fill also the "Authentication Methods" like USER
Transaction OA2C_CONFIG#
Stored at t.oa2c_client.At "User E-Mail for SAML 2.0 Name ID" you can have the options specified at CL_OA2C_SAML20_ASSERTION->BUILD_NAME_ID().
By default the local SAP username is passed to SF, but SF expects a userId, so this will not work.
The only option which made sense to me is to use 998 and specify the userId as Alias at the SAP user, see below
Client Secret: is mandatory, but does NOT matter here (use anything like xxx) Token Endpoint: <sf_host>/oauth/token enable Form Fields, Header Fields, Current user related, SAML 2.0 Bearer Assertion SAML 2.0 Audience = www.successfactors.com SAML 2.0 Recipient = token endpoint User E-Mail for SAML 2.0 Name ID = see above (998) SSL Client PSE = choose Default or Anonym (where you put the SF general SSH certificate)
OAuth #
User E-Mail for SAML 2.0 Name ID You can have only upper case ALIAS, so the userId must be uppercase too (or just numbers) !es_saml20_name_id-_value = to_lower( es_saml20_name_id-_value ).
Create BAdIs, copy/adjust classes#
Note: use always same case to avoid mixing up at all artifacts: Profile, Type, Application ID, Service Provider Type, SSF ID, ServerCL_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 => replace 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
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
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.
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 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_old_app_name TYPE string, lv_new_app_name TYPE string. lv_old_app_name = 'ZOACQ'. " erase former custom ones, set blank if none lv_new_app_name = ''. IF lv_old_app_name <> ''. DELETE FROM ssfapplic WHERE applic = lv_old_app_name. DELETE FROM ssfapplict WHERE applic = lv_old_app_name. WRITE: / |deleted { lv_old_app_name }, rc={ sy-subrc }|. ENDIF. IF lv_new_app_name <> ''. 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 }|. ENDIF. ENDFORM.Add SFF ID specific parameters with
- x.SSFA (t.SSFAPPLIC) or SM30 > VSSFARGS (x.SIMG > Multi Bank Connectivity Connector > Maintain SSF Application Parameters)
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)
SF Token lifetime#
With r.OA2C_GENERIC_ACCESS you can see we get a token which is valid 24h. The token metadata are stored at table OA2C_TOKEN_ADM for the current user and it is reused.In other words: You can skrew up configuration now for the next 24h but the connection still works.
To re-authenticate you can potentially use CL_OA2C_CLIENT->DELETE_TOKENS() or use r.OA2C_GENERIC_ACCESS.
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
- you have a mismatch in the codes/attributes in the custom classes of the two BAdIs
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
- you use 998, the alias is always upper case, but the SF userid is lower case
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"
400 - Parameter "company_id" is required in the OAuth request#
You haven't created the BAdIs and copied/adopted the classes to provideNo implementation exists for BAdI CLB2_OAUTH2_IMPL#
- Enhancement Implementation SMI_OAUTH2_AUTH_MAP > Add filter