HttpClientErrorException: 401 Unauthorized basic authentication - java

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.

Related

Need help to Bypass SSL certificate validation with rest template

I have one requirement i.e. to bypass SSL verification while connecting to webservice using rest template.
Currently I am implementing proxy to rest template via below code.
SimpleClientHttpRequestFactory clientHttpRequestFactory = new
SimpleClientHttpRequestFactory();
Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(proxyHost,
Integer.parseInt(proxyPort)));
clientHttpRequestFactory.setProxy(proxy);
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
ResponseEntity<String> responseEntity= restTemplate.exchange(url,HttpMethod.POST,
entity,String.class);
response = responseEntity.getBody();
How can I modify my Rest template so while connecting to URL it doesn't look for SSL certificate Validation.
I do checked couple of solutions online for this but all are implemented with
HttpComponentsClientHttpRequestFactory
which don't have provision to pass proxy host and server (Java.net.proxy object).
Can anyone help me here, I am stuck from long on this.
Solution I found online is below
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(csf)
.build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
restTemplate = new RestTemplate(requestFactory);
Thanks,
Anshu

Spring Boot Webclient with NTLM Authentication

I am using Spring WebClient to hit a Rest Service which requires NTLM Authentication. It works in Postman like below:
Hit the URL - http://example.com:83/api/auth/token with authentication as NTLM authentication and provide the user name and password. When hitting this service, it returns a token.
This token has to be passed in header as bearer token for the actual post service -
http://example.com:89/api/v1/employee
But when I tried the same using Spring WebClient, I am facing 401 - Unauthorized error. Below the code snippet I am using.
BasicCredentialsProvider tokenProvider = new BasicCredentialsProvider();
tokenProvider.setCredentials(
new AuthScope("http", "example.com", 83, "/api/auth/token", StandardAuthScheme.NTLM),
new NTCredentials("testuser", "pwd".toCharArray(), null, null)
);
webClient = WebClient.builder()
.clientConnector(new HttpComponentsClientHttpConnector
(HttpAsyncClients
.custom()
.setDefaultCredentialsProvider(tokenProvider)
.setTargetAuthenticationStrategy(DefaultAuthenticationStrategy.INSTANCE)
.setDefaultRequestConfig(
RequestConfig.custom()
.setAuthenticationEnabled(true)
.setTargetPreferredAuthSchemes(Collections.singletonList(StandardAuthScheme.NTLM))
.setExpectContinueEnabled(true)
.build())
.build()))
.build();
ParameterizedTypeReference<LinkedHashMap<String, Object>> result =
new ParameterizedTypeReference<LinkedHashMap<String, Object>>() {};
Map<String, Object> body = new HashMap<>();
body.put("test-key", "value");
webClient.post().uri("http://example.com:89/api/v1/employee").contentType(MediaType.APPLICATION_JSON).accept(MediaType.ALL).bodyValue(body).retrieve().bodyToMono(result).block();
Is this right approach?

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.

Spring RestTemplate with NTML Authentication

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 .?

Categories