Mockserver not responding running over https - java

My mockserver is running on a apache https connector over port 8443. But when I try to load the expectation using the following it does nothing. However when I use http connector it works like a charm.
new MockServerClient(ip, Integer.parseInt(port), contextPath)
.when(request, times, timeToLive)
.respond(response);
Based on my understanding it will use the http connector so I also tried
MockServerClient client = new MockServerClient(ip, Integer.parseInt(port), contextPath);
HttpForward httpForward = new HttpForward()
.withHost(ip)
.withPort(Integer.parseInt(port))
.withScheme(HttpForward.Scheme.HTTPS);
// when
ForwardChainExpectation forwardChainExpectation = client.when(request);
forwardChainExpectation.forward(httpForward);
What am I missing?
Can the mock server work over a https connector?

Related

Redirect HTTP to HTTPS on the same port with Jetty --- identifying http vs. https from the Request

Starting with Jetty 9.4.? it is possible to run HTTP and HTTPs on the same port. The gist of it is:
HttpConnectionFactory http = new HttpConnectionFactory();
SslConnectionFactory https = new SslConnectionFactory(sslCtxFactory, http.getProtocol());
DetectorConnectionFactory conFactory = new DetectorConnectionFactory(https);
ServerConnector connector = new ServerConnector(server, conFactory, http);
Since I only want to serve HTTPS, I would like to redirect each and every http://host:port/stuff to https://host:port/stuff. I know how to redirect with either subclass of RedirectRule or just with a handler called early.
The thing I am struggling with is: how do I figure out from the request that the connection is HTTP and not HTTPS?
When I look at the Request in the debugger, I found no hints, everything looks as if it is http even if the connection is https, Request.isSecure() is false, scheme is http and so on. The best thing I could come up with was:
if (Request.getHttpChannel().getEndPoint() instanceof SslConnection.DecryptedEndPoint())
Here is an annotated and clipped stack trace showing how my handlers are wrapped into each other:
at server.HttpToHttpsRedirectRule.matchAndApply(HttpToHttpsRedirectRule.java:34)
"^^ Here I do the matchAndApply myself and then use a jetty RedirectRule.apply"
"The redirect works OK, but figuring whether it is HTTPS does not work"
at org.eclipse.jetty.rewrite.handler.RuleContainer.apply(RuleContainer.java:166)
at org.eclipse.jetty.rewrite.handler.RuleContainer.matchAndApply(RuleContainer.java:145)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:317)
at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:766)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at server.LogHandler.handle(LogHandler.java:33)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
"^^^ the outermost handler"
[clip]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
"^^^ we decoded the ssl and feed the lower levels plain HTTP"
[clip]
at org.eclipse.jetty.io.ssl.SslConnection$1.run(SslConnection.java:146)
"^^^ we are in SSL"
It is in my HttpToHttpsRedirectRule where I would like to figure out which connection it is. Is there a saner solution than the instanceof mentioned above?
To make sure the original scheme (and possibly more) information is kept, it is necessary to add a SecureRequestCustomizer to the http configuration like this:
HttpConfiguration httpConf = new HttpConfiguration();
httpConf.addCustomizer(new SecureRequestCustomizer());
HttpConnectionFactory http = new HttpConnectionFactory(httpConf);
SslConnectionFactory https = new SslConnectionFactory(sslCtxFactory, http.getProtocol());
DetectorConnectionFactory conFactory = new DetectorConnectionFactory(https);
ServerConnector connector = new ServerConnector(server, conFactory, http);
The crucial hint was found in the jetty mailing list.

org.jolokia.client.exception.J4pException: IO-Error while contacting the server: javax.net.ssl.SSLException: hostname in certificate didn't match

I am using jolokia client to connect to my fuse server, which is using https for web. I am getting the below exception.
org.jolokia.client.exception.J4pException: IO-Error while contacting the server: javax.net.ssl.SSLException: hostname in certificate didn't match: <10.16.205.20> !=
at org.jolokia.client.J4pClient.mapException(J4pClient.java:333)
at org.jolokia.client.J4pClient.execute(J4pClient.java:198)
at org.jolokia.client.J4pClient.execute(J4pClient.java:168)
at org.jolokia.client.J4pClient.execute(J4pClient.java:117)
I have already imported the certificate of 10.16.205.20 to my local truststrore (cacerts) from where my client application is running jolokia client. I have also verified the hosts file have entry for the domain that is being used in the certificate on 10.16.205.20 server. I am using the below code to connect.
J4pClient client = J4pClient.url(baseUrl).user(user.getName()).password(user.getPassword()).authenticator(new BasicAuthenticator().preemptive()).build();
J4pExecRequest request = new J4pExecRequest("org.apache.karaf:type=bundles,name=root","list");
J4pExecResponse response = client.execute(request);
JSONObject obj = response.asJSONObject();
((CloseableHttpClient)client.getHttpClient()).close();
This code is running fine with the server deployed with http. Please let me know, if I am missing something.
You need to let your client use a ConnectionSocketFactory that bypasses this check.
For instance take a look at the following code (Code is Kotlin but you can easily translate it to java, I guess)
val sslCtx: SSLContext = SSLContexts
.custom()
.loadTrustMaterial(null, TrustSelfSignedStrategy())
.build()
val cf: ConnectionSocketFactory = SSLConnectionSocketFactory(sslCtx, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
J4pClient.url(s.jolokiaUrl)
.sslConnectionSocketFactory(cf)
.connectionTimeout(timeout.toMillis().toInt())
.build()

Jetty on Heroku: how to tell in code if https was used

I have some servlets running in Jetty, deployed on Heroku, handling POST requests.
Some, but not all, POST requests MUST come over https. Whether or not a request should be forced to be on https depends on the http body of the POST request.
I need to figure out, from inside the servlet, whether the incoming request used https (SSL) or not, so that I can send the appropriate response. However, nothing I have tried seems to work.
I tried the obvious HttpServletRequest.getProtocol() but that apparently returns the same constant whether the protocol was http or https.
I tried HttpServletRequest.isSecure() however that is returning false even though my test request was sent to a url starting with https://
When I call HttpUtils.getRequestURL( HttpServletRequest ).toString(); I get an apparrently reconstructed url that starts with "http://" even though my test request was sent to a url starting with "https://"
According to the post "Enforce HTTPS with Embedded Jetty on Heroku" heroku has some load balancers, and I should get the value of the "x-forwarded-proto" header. That header is blank.
FYI I am using the default SSL endpoint provided by the heroku api -- I am not using their SSL Endpoint extension, because this url is not being loaded in a browser (so I don't need a custom domain in the url).
Can anyone tell me how to tell if HTTPS was used in the incoming request?
I know nothing about Heroku, but if you're programmatically configuring Jetty (as opposed to using the XML configuration), you likely need to add the SecureRequestCustomizer to your HttpConfiguration. It sets the secure flag on the requests, as well as setting the scheme to HTTPS. You can find examples here, but briefly:
final HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setSecurePort(httpsPort);
final ServerConnector httpConnector = new ServerConnector(server,
new HttpConnectionFactory(httpConfig));
httpConnector.setPort(httpPort);
server.addConnector(httpConnector);
final HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
httpsConfig.addCustomizer(new SecureRequestCustomizer()); // !!!
final HttpConnectionFactory httpsFactory = new HttpConnectionFactory(httpsConfig);
final SslConnectionFactory sslFactory = new SslConnectionFactory(sslCtx,
httpsFactory.getProtocol());
final ServerConnector httpsConnector = new ServerConnector(server,
sslFactory, httpsFactory);
httpsConnector.setPort(httpsPort);
server.addConnector(httpsConnector);
I too found it rather surprising that this poorly documented step was necessary.

Do Jersey client support NTLM proxy

I'm trying to make a jersey client call using NTLM proxy? is that possible as i was not able to get any clear information on the same. Did anyone tried before?
Yes it is possible to configure the Jersey Client to connect through a proxy server that requires NTLM authentication.
Here is a simplified code snippet that prepares a suitable ClientConfig that should work with Jersey v2.5+:
final ClientConfig config = new ClientConfig();
config.property(ClientProperties.PROXY_URI, "http://myproxy.com:8000");
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
final AuthScope ntlmAuthScope =
new AuthScope("myproxy.com", 8000, AuthScope.ANY_REALM, "NTLM");
credentialsProvider.setCredentials(
ntlmAuthScope,
new NTCredentials("user", "password", "hostname", "domain") );
config.property(
ApacheClientProperties.CREDENTIALS_PROVIDER, credentialsProvider);
config.connectorProvider(new ApacheConnectorProvider());
Client client = ClientBuilder.newClient(config);
Please note: I am using the Apache HttpClient connector with Jersey Client - you may require slightly different code if you are using another client transport connector.
You may also need to add the following line to your code if you want your POST/PUT requests to be buffered (and therefore repeatable) in response to any 407 authentication challenges that come back from your proxy server:
config.property(ClientProperties.REQUEST_ENTITY_PROCESSING,
RequestEntityProcessing.BUFFERED);

Using Java, Need to establish an https connection via proxy

I need to establish and send/read over/from an https connection (to a website of course) but through an http proxy or SOCKS proxy. A few other requirements
supports blocking (I can't use non-blocking/nio)
isn't set as an environment or some other global scope property (there are multiple threads accessing)
I was looking into HttpCore components but I did not see any support for blocking https.
Look at the java.net.Proxy class. That does what you need. You create one, and then pass it to the URLConnection to create the connection.
To support per-thread proxy, your best bet is Apache HttpClient 4 (Http Components Client). Get the source code,
http://hc.apache.org/downloads.cgi
It comes with examples for both HTTP proxy and SOCKS proxy,
ClientExecuteProxy.java
ClientExecuteSOCKS.java
Did you look at Apache HTTP Client? Haven't used it in ages but I did use it to pick a proxy server dynamically. Example from site here:
HttpClient httpclient = new HttpClient();
httpclient.getHostConfiguration().setProxy("myproxyhost", 8080);
httpclient.getState().setProxyCredentials("my-proxy-realm", " myproxyhost",
new UsernamePasswordCredentials("my-proxy-username", "my-proxy-password"));
GetMethod httpget = new GetMethod("https://www.verisign.com/");
try {
httpclient.executeMethod(httpget);
System.out.println(httpget.getStatusLine());
} finally {
httpget.releaseConnection();
}
System.setProperty("http.proxyHost", "proxy.com");
System.setPropery("http.proxyPort", "8080");
URL url = new URL("http://java.sun.com/");
InputStream in = url.openStream();
http://java.sun.com/javase/6/docs/technotes/guides/net/proxies.html

Categories