on 2021 Apr 27 4:38 PM
I am attempting to call the Okta 'Get User with ID' service from an ABAP program. The call is returning a 403 status with a reason of Forbidden and I cannot determine why. Any help or guidance on what I am doing wrong is appreciated. Also, if I have selected the wrong tags then please feel free to direct me to the correct tags. Thanks.
I am able to make this call from Postman. The documentation for the call can be found at https://developer.okta.com/docs/reference/api/users/. The Request example is:
curl -v -X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: SSWS ${api_token}" \
"https://${yourOktaDomain}/api/v1/users/00ub0oNGTSWTBKOLGLNR"
Below is the pertinent ABAP code with the Okta token replaced with 'xxxxxxxx', our domain replaced with <myOktaDomain>, my Okta ID and SAP user name replaced with 'XXXXXX' and my password onto the SAP client replaced with 'xxxxxxxx'.
A few more details:
According to Okta, this is not using an OAuth authentication.
Our SAP instance is behind the firewall.
A similar, but simpler, call to a weather service works.
REPORT y_okta_call.
DATA: lo_http_client TYPE REF TO if_http_client,
lv_service TYPE string,
lv_result TYPE string.
DATA: go_http_client TYPE REF TO if_http_client,
go_rest_client TYPE REF TO cl_rest_http_client.
*Declarations for Data references
DATA:lo_json TYPE REF TO /ui2/cl_json.
DATA: lr_json TYPE REF TO /ui2/cl_json.
lv_service = 'https://<myOktaDomain>.okta.com/api/v1/users/XXXXXX'.
lv_service = lv_service && '?&format=json'.
cl_http_client=>create_by_url(
EXPORTING
url = lv_service
IMPORTING
client = go_http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4 ).
CONSTANTS gc_auth TYPE string VALUE 'Authorization'.
CONSTANTS gc_content_type TYPE string VALUE 'Content-Type'.
CONSTANTS gc_content_value TYPE string VALUE 'application/json'.
CONSTANTS gc_accept TYPE string VALUE 'Accept'.
CONSTANTS gc_accept_value TYPE string VALUE 'application/json'.
CONSTANTS: gc_e TYPE dd26e-enqmode VALUE 'E'.
DATA gv_auth_val TYPE string.
gv_auth_val = 'SSWS xxxxxxxx'.
CALL METHOD go_http_client->request->set_header_field
EXPORTING
name = gc_accept
value = gc_accept_value.
CALL METHOD go_http_client->request->set_header_field
EXPORTING
name = gc_content_type
value = gc_content_value.
CALL METHOD go_http_client->request->set_header_field
EXPORTING
name = gc_auth
value = gv_auth_val.
go_http_client->authenticate( username = 'XXXXXX' password = 'xxxxxxxx' ).
" set http protocol version
go_http_client->request->set_version(
if_http_request=>co_protocol_version_1_0 ) .
*Create REST Client object
CREATE OBJECT go_rest_client
EXPORTING
io_http_client = go_http_client.
TRY.
go_rest_client->if_rest_client~get( ).
DATA(lo_response) = go_rest_client->if_rest_client~get_response_entity( ).
DATA(lv_http_status) = lo_response->get_header_field( '~status_code' ).
IF lv_http_status NE 200.
*HTTP Request Failed
DATA(lv_reason) = lo_response->get_header_field( '~status_reason' ).
*STOP Processing
RETURN.
ENDIF.
*Receive the response data in JSON.
DATA(lv_json_data) = lo_response->get_string_data( ).
IF go_http_client IS BOUND.
go_http_client->refresh_response( ).
"Close HTTP session (Exception HTTP_NO_MEMORY)
go_http_client->close( ).
ENDIF.
*Collect into the exception table.
CATCH cx_rest_client_exception INTO DATA(lo_rest_client_exception).
ENDTRY.
Request clarification before answering.
Don't you get an token back and afterwards you can run the request for the user?
I would say you have to run the auth-process and afterwards you can run your user-request.
At least I read the documentation that way..
https://developer.okta.com/docs/reference/api/authn/#primary-authentication-with-trusted-application
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks Florian. This is very insightful. I cannot claim to be an expert on this and I had wondered the same. But I believe the Authentication API is for logging a user onto Okta: "The API is targeted for developers who want to build their own end-to-end login experience to replace the built-in Okta login experience". We are able to call Okta from SuccessFactors and I have confirmed with the SuccessFactors developer that they do not pass a device token to an Authentication API to receive back a token. They simply call the "Get User with ID" and pass our api token. I see that I did not do a good job of pasting the Request Example into the question. Here it is again:
curl -v -X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: SSWS ${api_token}" \
"https://${yourOktaDomain}/api/v1/users/00ub0oNGTSWTBKOLGLNR"
Hello Paul,
I don't see in Okta documentation why you are setting go_http_client->authenticate.
This method, I think, overrides your "Authorization" header with "Basic username:password(converted to base64)" and therefore your token is lost.
Try removing that line:
o_http_client->authenticate( username ='XXXXXX' password ='xxxxxxxx').
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
41 | |
15 | |
10 | |
9 | |
6 | |
5 | |
5 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.