nuoritoveri
nuoritoveri

Reputation: 2544

Can JCIFS be used with Jersey?

I have trouble adding NTLM authentication to my existing application that uses Jersey and Apache HttpClient. I was only able to authenticate using JCIFS, the default NTLM authentication from HttpClient does not work (I get 401).

The example from Apache HttpClient page shows how to use CloseableHttpClient: https://hc.apache.org/httpcomponents-client-4.5.x/ntlm.html

Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
    .register(AuthSchemes.NTLM, new JCIFSNTLMSchemeFactory())
    .register(AuthSchemes.BASIC, new BasicSchemeFactory())
    .register(AuthSchemes.DIGEST, new DigestSchemeFactory())
    .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory())
    .register(AuthSchemes.KERBEROS, new KerberosSchemeFactory())
    .build();
CloseableHttpClient httpClient = HttpClients.custom()
    .setDefaultAuthSchemeRegistry(authSchemeRegistry)
    .build();

But with CloseableHttpClient I cannot use methods like target:

WebTarget target = client.target(this.my Address).path(elementPath)
            .resolveTemplate(P_ID, myId);

There is only execute.

I'm not sure if I should rewrite my whole application and use only basic HttpClient calls like:

HttpGet httpGet = new HttpGet(repositoryAddress + "/" + "element/70032_1498404600000(,,arm)");
CloseableHttpResponse response = httpClient.execute(httpGet);

or there is some other way to set AuthSchemes in javax.ws.rs.client.Client, which can be used in Jersey?

Upvotes: 1

Views: 801

Answers (2)

bmaupin
bmaupin

Reputation: 16005

You can use NTLM with Jersey and Apache HTTP client if you use jersey-apache-connector. Then you can override the auth schemes like this:

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.glassfish.jersey.apache.connector.ApacheClientProperties;
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;

ClientConfig clientConfig = new ClientConfig();

// Configure NTLM authentication
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new NTCredentials(username, password, null, null));
clientConfig.property(ApacheClientProperties.CREDENTIALS_PROVIDER, credentialsProvider);
clientConfig.connectorProvider(new ApacheConnectorProvider());

// Default to NTLM authentication
RequestConfig requestConfig = RequestConfig.custom().setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM)).build();
clientConfig.property(ApacheClientProperties.REQUEST_CONFIG, requestConfig);

Client client = ClientBuilder.newClient(clientConfig);

Sources:

Upvotes: 0

ProgramNerd
ProgramNerd

Reputation: 61

I faced similar issues and my approach was below :

1) If you are using ApacheConnectorProvider as Connector you can Override ApacheConnector code (found here https://github.com/jersey/jersey/tree/master/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector). In my case I had to create custom ConnectorProvider and Connector.

2) Create a custom property or use HttpClientContext.AUTHSCHEME_REGISTRY and put it in the ClientConfig ( This is how we set properties for client in Jersey Client).

3) The Custom connector gets called when you call builder.get( or post or any other method). In the custom connector you can check for the property set in the above step. If it is set, you can set the DefaultAuthSchemeRegistry just like it is specified for ClosableHttpClient(ApacheConnector uses ClosableHttpClient in its implementation).

This may be kind of a hack but works fine for me. Hope this helps :)

Upvotes: 3

Related Questions