Moving from a web service from HTTP to HTTPS - java

I have a web service on one server and a Java client on another. Currently all calls are being made over HTTP but I would like the service to be more secure with HTTPS and basic authentication, I only want my client to be able to make calls. My web server receiving the requests is Apache httpd.
I've set up directives in the apache conf as follows:
<Location /mypath>
Order Deny,Allow
Deny from all
Allow from all
AuthType Basic
AuthName "My Web Service Login"
AuthBasicProvider file
AuthUserFile "/usr1/apache/passwd/passwords"
Require user myuser
</Location>
The passwords file has only one entry, for myuser
<IfModule ssl_module>
ServerName www.myserver.com
SSLEngine on
SSLCACertificateFile "/usr1/apache/conf/ssl/myCAList.pem"
SSLCertificateFile "/usr1/apache/conf/ssl/myserver.crt"
SSLCertificateKeyFile "/usr1/apache/conf/ssl/myserver.pem"
SSLVerifyClient require
</IfModule>
I think I have the server set up correctly (posted just in case). However, I can't test this for another hour when I can safely restart apache.
What I need help with is I'm unsure of how to configure the client. Here is a simple example call (using httpclient 4.5.1) :
HttpClient client = HttpClient.createDefault();
HttpGet httpGet = new HttpGet(URI);
HttpResponse httpRes = client.execute(httpGet);
I know I need to specify https instead of http on the URI, but how do I
1) Send the username and password for the basic authentication
2) Make sure my client server trusts the certificate of the web service server
3) What certificates and such that I need on the client server for the SSL connection
Thank you!

Related

configure ssl certificate apache for 1 way authentication

I am using java application to send request to a URL. I have an apache server in the middle. So my application sends request to the apache server and the apache server then sends request to the actual server with which I want to communicate.
The server side has sent us a .cer certificate file which should be presented at the time of SSL handshake. The server side is not ready to share the private key (.key) file with us. How do I configure the certificate in the apache httpd config.
Currently I have below configuration at httpd side
httpd.conf
< VirtualHost apache-server-IP:443 >
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile /etc/httpd/conf/test.cer (certificate file provided by server side)
ProxyPass /api https://ServerIP:ServerPort/api/oauth/token
ProxyPassReverse /api https://ServerIP:ServerPort/api/oauth/token
< /VirtualHost >
I make a hit to the apache server using the URL (http://apache-server-ip:443/api/oauth/token) , which in turn sends request on https to actual server using proxypass.
I'm getting internal server error 500 from the server side.
Can anyone suggest how to configure the certificate in apache without using private key but only for presenting the certificate to the server.

java - send https request to server ip address throws SSLHandshakeException

I need to send post request to server ip through HTTPS protocol. Here is my code:
HttpClient httpClient = HttpClients.createDefault();
String address = "https://100.100.100.100:90"; //just an example
HttpPost httpPost = new HttpPost(address);
httpPost.addHeader("charset", "UTF-8");
//set post data(not important here)
...
HttpResponse response = httpClient.execute(httpPost);
the last line throws this exception:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
What's the problem and how can I solve this?
EDIT:
I don't know DNS name, so I need to use ip instead. I sent ajax request to that ip in browser, browser sends request, but requests stay in waiting mode. My Http Client is a simple java desktop application.
Probably the server you're trying to connect to doesn't accept requests using IP address.
In HTTP, this happens if the server is used for multiple domains / websites - it needs to know which one to give you and it does so based on the Host header. So if you want to connect by IP your client must be configured to send the correct Host (and must be able to do so).
Now in HTTPS protocol, on top of this the server also provides a server certificate during the handshake and this certificate is issued for a server hostname }likely a DNS name e.g. example.com) - again if you connect by IP and don't give your HTTP client any more info, the client cannot validate that the certifiate received from the server is issued for the correct hostname.

How to get NodeJS to proxy Client Certificates like Jetty Proxy

I am writing a NodeJS proxy that will replace a Java Jetty Proxy. I am using node-http-proxy. The only piece remaining is to have the original client certificate passed along to the proxied server.
From my understanding, the Java Servlet specification requires that a Servlet container pull the Client Certificate from an HTTPS request and store that as an attribute on the HttpServletRequest.
I am not sure how the Servlet Container handles the Attributes when proxying the request to a new server. I presume that it is attaching them somehow either as headers or by some other means.
Does anyone know how those attributes (specifically the javax.servlet.request.X509Certificate) are passed on a proxied HTTPS request? And two, how do I achieve the same functionality using NodeJS.
In the event that is helps someone else out... The issue turned out to be the node module I was using (node-http-proxy) wasn't reusing the HTTP server connection certificates. That is, when attempting to create a connection with the proxy server, it was using a default (generated) certificate.
To properly connect with the proxy server, I had to pass the ca, pfx, and passphrase to the proxy connector.
const ca = ...
const pfx = ...
const passphrase = ...
// proxy connection
server.web(req, res, { ca: ca, pfx: pfx, passphrase: passphrase }, function(err) {});
After doing so, the Proxy server was able to pull and validate the certificate.

RestTemplate: login by certificate

I am writing a java rest-client to fetch data from the web App. I am trying to use client authentication(login using client certificate) mechanism using spring's RestTemplate to get authenticated on server.
Here are the steps that I did.
Server side:
Configure the web server to allow certificate based login. Set "clientAuth"= "want" in server.xml
Create a clients x509 certificate and add it into servers truststore.
Client Side
Initialize RestTemplate with clients trustStore and keyStore. For this I used org.apache.commons.httpclient.contrib.ssl.AuthSSLProtocolSocketFactory.
AuthSSLProtocolSocketFactory is initialized with client keystore in PKCS12 format, and client truststore (jks format).
Code looks like this:
CommonsClientHttpRequestFactory factory = (CommonsClientHttpRequestFactory) restTemplate.getRequestFactory();
HttpClient client = factory.getHttpClient();
client.getState().setAuthenticationPreemptive(false);
Protocol myHttps = new Protocol(HTTPS, secureProtocolSocketFactory, DEFAULT_HTTPS_PORT);
Protocol.registerProtocol(HTTPS, myHttps);
client.getHostConfiguration().setHost("localhost", DEFAULT_HTTPS_PORT, myHttps);
When I am making rest calls into server I am expecting the request to get authenticated by certificate. But I am getting http 403-forbidden error. It seems that restTemplate is trying to authenticate the request by basicCredentials, where my intent is to authenticate using certificate.
Following is the output logged by http client:
MultiThreadedHttpConnectionManager:390 - HttpConnectionManager.getConnection: config = HostConfiguration[host=https://<server-ip>], timeout = 0
MultiThreadedHttpConnectionManager$ConnectionPool:739 - Allocating new connection, hostConfig=HostConfiguration[host=<server-ip>]
HttpMethodDirector:160 - Preemptively sending default basic credentials
HttpMethodDirector:277 - Authenticating with BASIC <any realm>#<server-ip>:443
HttpMethodParams:355 - Credential charset not configured, using HTTP element charset
HttpConnection:691 - Open connection to 10.112.253.152:443
HttpMethodBase:1235 - Adding Host request header
RestTemplate:559 - GET request for "https://<server-ip>:443/url/" resulted in 403 (Forbidden)
Is there anything else that needs to be configured on RestTemplate to get authenticated using client certificate?

How to login to SSL website using java without having the server certificate

I am able to connect to https url using java. But my concern is to log in to a SSL website by providing username and password. I have done it using the PostMethod of HTTP Client, but not sure how the same can be achieved for HTTPS URL's?

Categories

Resources