JerseyClient using DefaultHttpClient - client

I need to access a JAX-WS webservice protected by SSL using Jersey Client. I have successfully got this working with limited configuration and just letting the Client use the default HTTPURLConnection API.
This approach wont work however for my overall solution because it does not allow me the flexibility to change the credentials used when making a request to the WS. I'm trying to use DefaultHTTPClient instead and then passing it to the Client object on intialization.
NTCredentials credentials = new NTCredentials("username", "password",
computerName, domainName);
DefaultHttpClient httpClienttemp = new DefaultHttpClient();
DefaultHttpClient httpClient = wrapClient(httpClienttemp);
httpClient.getCredentialsProvider().setCredentials(AuthScope.ANY, credentials );
ClientConfig config = new DefaultClientConfig();
The wrapClient method creates an X509TrustManager and overrides the necessary methods so that all certificates are accepted. It also creates a SchemeRegistry entry for https access on port 443. This configuration results in a Connection refused exception.
The strange thing is, if i add an additional entry in the SchemeRegistry for http and give it a port of 443 then the request does get sent however a Connection Reset exception then gets thrown.
The Url i use to create the WebResource object is https however the SOAPAction i declare in the header uses http. Any ideas where im going wrong?

This is a limitation of the default HTTP Client (com.sun.jersey.api.client.Client) documented in the Jersey docs. You will have to use Apache HTTP Client to achieve this functionality.
Looks like someone already recommended doing this in the answer to your previous question: Jersey Client API - authentication.
EDIT: Corrected reference to the default Jersey HTTP Client to avoid confusion.

Related

Camel: Calling a HTTPS REST endpoint with a proxy

I'm consuming data from a REST endpoint with in the middle of the route a proxy. I'm having CNTLM running locally (localhost:3128 ): it will authenticate for me on the corporate proxy, so I don't need to pass my credentials.
I have been unable to get my rest call to work, despite numerous attempts. For e.g., getting:
SSLException: Unrecognized SSL message
Connection handshake abruptly terminated
Connection reset
you name it, have got it
Below the simplest version of the many attempts made.
Apparently (from internet reading), that should work, but it doesn't.
How should Camel be configured, in particular camel-http ?
Notes:
The REST API I'm calling is using HTTPS but doesn't require a certificate.
The code works on my local machine when no proxy is involved. It fails on the intranet where there is a proxy
#Component
public class MyRoute extends RouteBuilder
public void configure() throws Exception {
//Tried different way to set the proxy, including inline with toD(...)
System.setProperty("https.proxyHost", "localhost");
System.setProperty("https.proxyPort", "3128");
getCamelContext().getGlobalOptions().put("http.proxyHost", "localhost");
getCamelContext().getGlobalOptions().put("https.proxyPort", "3128");
getContext().getGlobalOptions().put("https.proxyHost", "localhost");
getContext().getGlobalOptions().put("https.proxyPort", "3128");
from("timer:credentials?repeatCount=1")
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.setBody(simple(jsonAuth))
.to(baseUrlApi +"/v1/auth/tokens/?bridgeEndpoint=true")
.unmarshal().json(JsonLibrary.Jackson, AuthResponseDto.class)
.setHeader("Authorization", simple("Bearer ${body.data.accessToken.token}"))
// etc..
}
}

Client Registration with Spring-boot Oauth2 - tokenUri vs issuerUri

Sorry folks, this may be a newb question. I'm a little lost.
My Spring-boot environment provides me with keycloak for client authorization, it gives me these.
spring.security.oauth2.resourceserver.jwt.issuer-uri
spring.security.oauth2.client.provider.keycloak.issuer-uri
spring.security.oauth2.client.registration.keycloak.* # client-id, secret, provider, grant-type
I noticed on the ClientRegistration that .issuerUri(String uri) is not avaialbe until Spring-Security v5.4.x. I am using 5.3.5, although I could bump up. I am confused what the difference is. As I would expect, I get an error when I do .tokenUri(issuerUri). I believe they are different modes/API, but I am at a loss as to what I should set in the 5.3.5 API.
Caused by: org.springframework.security.oauth2.client.ClientAuthorizationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 405 Method Not Allowed: [{"error":"RESTEASY003650: No resource method found for POST, return 405 with Allow header"}]
So as a newb, I don't get why I have 4 choices of URI and what they do. Google and javadoc haven't been much help, so I figure I just don't know the right place to look to learn it. The only way I know how to fix this is to manual make my own HTTP call to the URI and get my Authentication token, but that would defeat the purpose of the Oauth2 library.
tokenUri represents the URI for the token endpoint. For example:
https://authz.example.org/auth/realms/myrealms/protocol/openid-connect/token
Whereas issuerUri is the URI that identifies the Authorization Server:
https://authz.example.org/auth
It's quite common for the issuer URI to be the root for more specific URIs like the token URI.
Regarding your specific error, I'd imagine that Keycloak is stating that you cannot POST to https://authz.example.org/auth, which is true. You should be POSTing to the token endpoint.
The issuer-uri Spring Boot property should cause Spring Security to look up the other endpoints and add them to a default ClientRegistration. Because of that, I'm not sure why you are also trying to programmatically configure ClientRegistration. That said, if you do need to programmatically create a ClientRegistration, you can use the issuer URI like so, and Spring Security will do the rest:
#Bean
ClientRegistrationRepository registrations() {
ClientRegistration registration = ClientRegistrations
.forIssuerLocation("https://authz.example.org/auth")
.build();
return new InMemoryClientRegistrationRepository(registration);
}

RestTemplate: Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter

I am using RestTemplate with custom HttpClient. My request is getting redirected to S3 but somehow it is carrying Authorization header along with it after redirection.
Httpclient is configured to use LaxRedirectStrategy, cookies are ignored.
Is there a way how to fix this issue or any insight?

How to make HTTP request from Okhttp Authenticator?

I'm using Okhttp3 and I want to build an OAuth2 Authenticator.
Sometimes, I need to make http requests from the Authenticator itself (ie: to refresh the token) but the api doesn't provide a way to do it.
For sure, I can create a new okhttp instance but I don't know if it is a recommanded practice.
Is it a best practice for my need?
It is not possible to do it out of the box but some workarounds can work:
create a new instance of OkHttpClient into the Authenticator, or
add a setHttpClient method in Authenticator
.
MyAuthenticator authenticator = new MyAuthenticator();
OkHttpClient client = new OkHttpClient.Builder()
.authenticator(authenticator)
.build();
authenticator.setHttpClient(client);
From: https://github.com/square/okhttp/issues/2733

Dynamic provider for a Marshalling web service outbound gateway

Is it possible to set a dynamic provider for a Marshalling web service outbound gateway?
I mean, if I try for example: http://100.0.0.1 and it not works, I would like to try http://100.0.0.2 instead
My current configuration:
MarshallingWebServiceOutboundGateway gw = new MarshallingWebServiceOutboundGateway(provider, jaxb2Marshaller(), jaxb2Marshaller());
Yes, that's true. Since MarshallingWebServiceOutboundGateway allows to inject DestinationProvider, you feel free to provide any custom implementation.
For your fault-tolerant use-case you should do: new URLConnection(url).connect() to test connection to the target server in that your DestinationProvider implementation.
UPDATE
But If I how can I test new URLConnection(url).connect() if I have https credentials, certificate or any kind of security
Well, another good solution from the Spring Integration is load-balancing and several subscribers to the same DirectChannel:
#Bean
public MessageChannel wsChannel() {
return new DirectChannel(null);
}
to switch of the default RoundRobinLoadBalancingStrategy.
And after that you can have several #ServiceActivator(inputChannel="wsChannel"). When the first one is fail, the message is sent to the second and so on, until the good result or the fall for each URL.

Resources