2009 Jun 08 8:58 PM
Hi,
I´m using an instance of the class CL_HTTP_CLIENT to make an HTTP request to a https server. as long as it requires an SSL authentication, it returns an ICM_HTTP_SSL_ERROR error message.
How do I tell my program to ask for user´s certificate, and use it in the http request?
I´m supossed to have hundreds of users online running this application (it´s over SRM 5.0). How can I reach this?
Thanks you very much.
Federico.
2009 Jun 09 3:42 PM
Thanks Olivier, it´s been very helpful.
However, I have some new doubts:
1. By creating a new client, you mean go to "Environment->SSL Client Identitites" in STRUST, right? Can I use a previously existing one?
2. I need this PSE client to have several 'identitites', I mean, to include several certificates from all my users. Is it possible? If it´s not; how should I do so?
3. When I had my new PSE client, and my HTTP RFC destination of type 'G' configured to use that PSE client, and when in abap I instantiate my http client (using CREATE_BY_DESTINATION method, from CL_HTTP_CLIENT class): How does SAP knows which certificate to use? Because there will be several users (hundreds) running this code to retrieve their specific data from a third party server.
How does SAP knows whom certificate must use?
I will appreciate any tip you could give to me.
Thanks in advance.
Federico.
2009 Jun 09 10:18 AM
Hi,
You have to create an SSL client PSE in transaction STRUST.
You have to create HTTP destination from SM59 and configure it to use HTTPS and authentication with the client certificate.
Then in your abap code you have to use the HTTP destination.
Regards,
Olivier
2009 Jun 09 3:42 PM
Thanks Olivier, it´s been very helpful.
However, I have some new doubts:
1. By creating a new client, you mean go to "Environment->SSL Client Identitites" in STRUST, right? Can I use a previously existing one?
2. I need this PSE client to have several 'identitites', I mean, to include several certificates from all my users. Is it possible? If it´s not; how should I do so?
3. When I had my new PSE client, and my HTTP RFC destination of type 'G' configured to use that PSE client, and when in abap I instantiate my http client (using CREATE_BY_DESTINATION method, from CL_HTTP_CLIENT class): How does SAP knows which certificate to use? Because there will be several users (hundreds) running this code to retrieve their specific data from a third party server.
How does SAP knows whom certificate must use?
I will appreciate any tip you could give to me.
Thanks in advance.
Federico.
2009 Jun 10 12:32 PM
Hello Frederico,
>1. By creating a new client, you mean go to "Environment->SSL Client Identitites" in STRUST, right? >Can I use a previously existing one?
I meant to create a new client SSL PSE. By default in a new Netweaver abap system, you have 3 of them : ANONYM, DFAULT and WSSE.
If you need more of them, you can create them with the menu "Go to-->Environment->SSL Client Identitites".
>2. I need this PSE client to have several 'identitites', I mean, to include several certificates from all my >users. Is it possible? If it´s not; how should I do so?
It seems that you want a different certificate per user. These client certificates in STRUST are designes to identify a SAP abap system, not human users. If you have 1000 users, you will not create 1000 certificates in STRUST !
Usually, you use only 2 entries here, one for anonymous HTTPS access and one authenticated HTTPS access. It is unusual to have several different identities for the same abap server. But it might be possible : for exemple, one identity on the intranet and an other one on the Internet.
>3. When I had my new PSE client, and my HTTP RFC destination of type 'G' configured to use that >PSE client, and when in abap I instantiate my http client (using CREATE_BY_DESTINATION method, >from CL_HTTP_CLIENT class): How does SAP knows which certificate to use? Because there will be >several users (hundreds) running this code to retrieve their specific data from a third party server.
>How does SAP knows whom certificate must use?
The certificate used will be the one defined in the HTTP destination.
You still seem to make the confusion between server client certificates and users client certificates.
a users client certificate is stored in the user's PC (or smartcard) and is used for HTTPS connections from the user's browser to the SSL server, not for an HTTPS connection from the ABAP server to another server.
Regards,
Olivier
2009 Jun 10 3:24 PM
Thank you very much Olivier.
Thanks for your time, your patience, and to share your knowledge so clearly!
Kind regards,
Federico.
2009 Jun 18 11:09 AM
Hi Federico,
I'm facing a similar task but I'm completly new in this area. Is it possible for you to provide some coding samples? That would be awesome! If not, maybe you could hint to some of the methods used or so?
Appreciated!
Best regards,
Melanie
2009 Jun 18 4:20 PM
Hi Mel,
Trust me, the code is very simple and is the least of the problems you might experience
Here you are:
data: client type ref to if_http_client,
content type xstring.
call method cl_http_client=>create_by_destination
exporting
destination = 'MY_HTTP_SSL_DESTINATION'
importing
client = client
exceptions
argument_not_found = 1
destination_not_found = 2
destination_no_authority = 3
plugin_not_active = 4
internal_error = 5
others = 6.
cl_http_utility=>set_request_uri( request = client->request
uri = 'https://www.something.com' ).
****Set the Request type to GET
client->request->set_header_field( name = '~request_method'
value = 'GET' ). "#EC *
****Make the call
client->send( ).
****Receive the Response Object
call method client->receive
exceptions
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
others = 4.
if sy-subrc ne 0.
data subrc type sysubrc.
data errortext type string.
call method client->get_last_error
importing
code = subrc
message = errortext.
write: / 'communication_error( receive )',
/ 'code: ', subrc, 'message: ', errortext.
exit.
else.
****Get the response content in Character format
content = client->response->get_data( ).
break-point.
endif.
* close
call method client->close
exceptions
http_invalid_state = 1
others = 2.
First, you must create an HHTP RFC destination in SM59, and configure client & server certificates in STRUST (that´s what i´m still trying to do successfully).
Only then this code will work.
Regards,
Federico.
2009 Jun 22 11:34 AM
Hi again Federico,
Cheers for that. Really appreciated!
I unfortunatelly have never worked with http client request & response. So I'm glad to have an example now. The example in the SAP Help wasn't that clear to me.
As for the RFC destination and server certificate settings; I'm in the lucky position of not doing those... A colleague of mine is working on that at the moment... Or should I say he's fighting with it? He gets error messages from SM59 when he tries to test the RFC destination. So I guess until that's solved I can't test my coding.
I have few questions about sending data - hope you don't mind me asking.
When I use GET do I have to set the URI like following?
https://www.somewhere.com/data1=value1&data2=value2
How would I send data using POST? With method SET_CDATA ?
How does that data have to look?
I have a string which has values that are delimited by cl_abap_char_utilities=>newline.
Kind regards,
Melanie
2009 Jun 18 4:23 PM
I´m sorry: 'content' should have been declared as STRING, not XSTRING.
Bye.
2009 Jun 22 3:58 PM
Hi Mel.
I would suggest you to make a new thread, so you can give points for the help you receive, which is the idea of the community.
1. Your URL should look like that, it´s correct, it´s the same string you would call from any browser.
2. Your POST, once you have created your HTTP destination, and have instantiated it, might look like this:
data: my_post type string,
xml_xstring type xstring.
client->request->set_method( exporting method = if_http_request=>if_http_entity~co_request_method_post ).
client->request->set_header_field( exporting name = '~server_protocol' value = 'HTTP/1.1' ).
client->request->set_header_field( exporting name = 'Content-Type' value = 'text/xml' ).
client->request->set_cdata( exporting data = my_post offset = 0 ).
client->send( exceptions http_communication_failure = 1 http_invalid_state = 2 ).
client->receive( exceptions http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 ).
if sy-subrc eq 0.
xml_xstring = client->response->get_data( ).
endif.
You can set as many headers as you want, it´s only an example.
Regards,
Federico.
2009 Jun 22 4:03 PM
By the way, 'my_post' variable is supossed to be filled with your POST string before calling set_cdata method!
Bye
2009 Jun 23 6:40 AM
Hi again Frederico,
And also thanks again! Very appreciated!
And you're right about maknig my own post, sorry for that. Wish I could give you some points now. I'll make my own post and let ya know if I should run into further walls.
Cheers,
Melanie