Spring RestTemplate with NTML Authentication - java

I am consuming a service which is NTML Authentication .
Below is my configuration
But i am getting 400 Bad Request
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
RequestConfig.Builder requestBuilder = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(10000);
Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider> create().register(AuthSchemes.NTLM, new NTLMSchemeFactory())
.register(AuthSchemes.NTLM, new SPNegoSchemeFactory()).build();
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new NTCredentials("MyUsername", "MyPassword", "", "MyDomain"));
HttpClientBuilder builder = HttpClientBuilder.create().setConnectionManager(cm).setDefaultRequestConfig(requestBuilder.build())
.setDefaultAuthSchemeRegistry(authSchemeRegistry).setDefaultCredentialsProvider(credentialsProvider);
HttpHeaders headers = new HttpHeaders();
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(builder.build()));
List<ClientHttpRequestInterceptor> interceptors
= restTemplate.getInterceptors();
if (CollectionUtils.isEmpty(interceptors)) {
interceptors = new ArrayList<>();
restTemplate.setInterceptors(interceptors);
}
restTemplate.getInterceptors().add(clientHttpRequestInterceptor);
The same service i am able to consume using apache http client.
Does spring supports NTML Authentication .?

Related

Closing socket HttpClient in bean (CloseableHttpClient) - need to do this? JAVA

Should I worry about to release a socket allocated by clientBuilder.build() in this code:
#Bean("proxyRestTemplate")
#LoadBalanced
public RestTemplate proxyRestTemplate() {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(proxyUrl, proxyPort),
new UsernamePasswordCredentials(proxyUsername, proxyPassword)
);
HttpHost myProxy = new HttpHost(proxyUrl, proxyPort);
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.setProxy(myProxy).setDefaultCredentialsProvider(credsProvider).disableCookieManagement();
HttpClient httpClient = clientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new CustomHttpComponentsClientHttpRequestFactory();
factory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(factory);
restTemplate.getInterceptors().add(new BasicAuthenticationInterceptor(basicAuthUsername, basicAuthPassword));
return restTemplate;
}
I sincerely hope this will be a short and simple question
Thank you in advance for your help.

Spring Boot Application Proxy Authentication 407

Hi I got proxy 407 authentication error in my spring boot project.I tried two scenario in these scenarios proxyHost and proxyPort values are working but username and password has no effect?Is any one face this scenario?In my local machine when I give port and host and giving no username password,it works my local user and work,but I give username and password in wrong format to see its effect?I doesnt effect.
Also in server I got 407 authentication proxy exception.How can pass proxy username and password in spring boot?thanks
I add jvm parameters but proxyuser and proxyPassword no effect
-Dhttps.proxyHost=something -Dhttps.proxyPort=5555-Dhttps.proxyUser=xxx -Dhttps.proxyPassword=yyy
I also add someproxy code to myresttemplate builder but it has no effect.
RestTemplate restTemplate=new RestTemplateBuilder()
.build();
int proxyPortNum =5555;
String proxyHost="something";
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(proxyHost, proxyPortNum), new UsernamePasswordCredentials("myname", "333"));
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.useSystemProperties();
clientBuilder.setProxy(new HttpHost(proxyHost, proxyPortNum));
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
CloseableHttpClient client = clientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(client);
restTemplate.setRequestFactory(factory);
you should try something like this:-----
private RestTemplate createRestTemplate() throws Exception {
final String username = "myname";
final String password = "333";
final String proxyUrl = "something";
final int port = 5555;
HttpHost myProxy = new HttpHost(proxyUrl, port);
HttpClientBuilder clientBuilder = HttpClients.custom();
List<Header> headers = new ArrayList<>();
BasicHeader authHeader = new BasicHeader("Authorization",base64authUserPassword());
headers.add(authHeader);
RequestDefaultHeaders reqHeader = new RequestDefaultHeaders(headers);
clientBuilder.addInterceptorLast(reqHeader);
clientBuilder.setProxy(myProxy).disableCookieManagement();
HttpClient httpClient = clientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(httpClient);
return new RestTemplate(factory);
}
public String base64authUserPassword() {
byte[] baseencode = Base64.getEncoder().encode((username + ":" + password).getBytes());
return "Basic " + new String(baseencode);
}
Hope it will resolve your issue.

Why is my Session gone when using RestTemplate to access Spring MVC?

I am trying to access a Spring MVC app. That uses a CSRF Token. I do an initial GET to receive the Token. Then add it to my POST with my JSESSIONID. However, during debug the Server app doesn't find my JSESSIONID. And therefore, doesn't authenticate my token, and gives me 403.
I can't tell but it looks like my GET JSESSIONID doesn't get saved in the server HTTP Session repository.
Is there a way, to validate:
The session is in the server context?
Am I sending the correct header data?
Here's my code:
public String testLogin() {
ResponseEntity<String> response =
restTemplate.getForEntity(LOGIN_RESOURCE_URL, String.class);
List<String> cookies = new ArrayList<String>();
cookies = response.getHeaders().get("Set-Cookie");
String[] firstString = cookies.get(0).split("=|;");
String jsessionPart = firstString[1];
String[] secondString = cookies.get(1).split("=|;");
String tokenPart = secondString[1];
BasicCookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("JSESSIONID",
jsessionPart);
cookie.setDomain(".mydomain.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);
BasicClientCookie cookie2 = new BasicClientCookie("X-XSRF-TOKEN",
tokenPart);
cookie2.setDomain(".mydomain.com");
cookie2.setPath("/");
cookieStore.addCookie(cookie2);
HttpClient client = HttpClientBuilder
.create()
.setDefaultCookieStore(cookieStore)
.disableRedirectHandling()
.build();
HttpComponentsClientHttpRequestFactory factory = new
HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(client);
RestTemplate postTemplate = new RestTemplate(factory);
HttpEntity<?> requestEntity = new HttpEntity<Object>(body, headers);
ResponseEntity<String> response = postTemplate.exchange(loginUserUrl,
HttpMethod.POST, requestEntity,String.class);
To your code sample I added user name and password plus changed the content type. The 403 still happens whether i sent content type or not:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// if you need to pass form parameters in request with headers.
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
try {
map.add( URLEncoder.encode("username", "UTF-8"),
URLEncoder.encode("userdev", "UTF-8") );
map.add(URLEncoder.encode("password", "UTF-8"),
URLEncoder.encode("devpwd","UTF-8") );
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>
(map, headers);
ResponseEntity<String> response =
this.restTemplate(builder).exchange(RESOURCE_URL, HttpMethod.POST,
requestEntity, String.class);
Instead of messing around with cookies yourself let the framework, Apache HttpClient, handle this for you. Configure the RestTemplate to work with a properly configured HttpClient.
Something like this should do the trick
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.requestFactory(this::requestFactory)
.build();
}
#Bean
public HttpComponentsClientHttpRequestFactory requestFactory() {
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.DEFAULT)
.setExpectContinueEnabled(true)
.build();
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setDefaultCookieStore(new BasicCookieStore())
.setDefaultRequestConfig(defaultRequestConfig).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
return requestFactory;
}
This will configure the RestTemplate to use a HttpClient that stores cookies in a CookieStore in between requests. Reuse the configured RestTemplate and don't create a new one because you might need it.

REST webservice call for HTTPS link - 400 Bad Request error

Using SOAP UI, I am able to successfully invoke the REST GET call with basic authentication
GET https://app.test.com/testing/rest/authentication-point/authentication HTTP/1.1
Accept-Encoding: gzip,deflate
Authorization: Basic aPOjYVclOmIzABFhZjVpJES=
Host: app.test.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
I received response code as 200.
Similar request, When I tried to invoke via java client, it is giving 400 status code.
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("User", "Password"));
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = null;
response = client.execute(
new HttpGet("https://app.test.com/testing/rest/authentication-point/authentication"),
context);
int statusCode = response.getStatusLine().getStatusCode();
This code worked properly when the host was HTTP. Recently a VIP is added and made as HTTPS, after which it is not working. Please suggest a fix for this.
You need to use ssl with http client:
TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
SSLSocketFactory sf = new SSLSocketFactory(
acceptingTrustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", 8443, sf));
ClientConnectionManager ccm = new PoolingClientConnectionManager(registry);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("User", "Password"));
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
DefaultHttpClient httpClient = new DefaultHttpClient(ccm);
HttpGet getMethod = new HttpGet(new HttpGet("https://app.test.com/testing/rest/authentication-point/authentication"),context);
HttpResponse response = httpClient.execute(getMethod);
int statusCode = response.getStatusLine().getStatusCode();
After trying out so many options, below code worked for me.
HttpHost targetHost = new HttpHost("app.test.com", 443, "https");
AuthCache authCache = new BasicAuthCache();
authCache.put(targetHost, new BasicScheme());
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("User", "Password"));
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = null;
response = client.execute(
new HttpGet("https://app.test.com/testing/rest/authentication-point/authentication"),
context);
After defining a HTTP host with scheme as https, and setting them to context using AuthCache, the call went through successfully.

HttpClientErrorException: 401 Unauthorized basic authentication

Im trying to get the url with basic authentication. I set the user/password as given below. The same credential is working in postman.
String RELATIVE_IDENTITY_URL = "http://my_url/api/core/v3/people/email/abc#example.com";
RestTemplate restTemplate;
Credentials credentials;
//1. Set credentials
credentials = new UsernamePasswordCredentials("admin", "admin");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials( AuthScope.ANY, credentials);
//2. Bind credentialsProvider to httpClient
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.setDefaultCredentialsProvider(credsProvider);
CloseableHttpClient httpClient = httpClientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new
HttpComponentsClientHttpRequestFactory(httpClient);
//3. create restTemplate
restTemplate = new RestTemplate();
restTemplate.setRequestFactory(factory);
//4. restTemplate execute
String url = RELATIVE_IDENTITY_URL;
String xml = restTemplate.getForObject(url,String.class);
System.out.println("Done");
I think the credentials are not set correctly. What is wrong here.?
Error:
Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 401 Unauthorized
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:667)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:620)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:580)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:287)
at com.src.AuthRestService.main(AuthRestService.java:85)
You are missing the auth header and setting the credentials in your rest template execution.

Categories