Could Not call Oauth 2 from RestTemplate - spring

I tried to call oauth 2 using Spring RestTemplate but ended up with this error 404 Not Found: [{"message":"no Route matched with those values"}]
below is my code .OauthRequest is class created by me .
String oauthurl = serverurl + GET_TOKEN;
HttpHeaders headers = buildHeader();
OauthRequest oathRequest = new OauthRequest();
oathRequest.setClient_id(clientid);
oathRequest.setClient_secret(clientsecret);
oathRequest.setAuthenticated_userid(usercode);
oathRequest.setScope(scope);
oathRequest.setGrant_type(grantTypePassword);
oathRequest.setProvision_key(key);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Host", hostname);
headers.set("Accept-Version", "1.0");
headers.set("Content-Length", MAX_TRANSFER_SIZE);
HttpEntity<OauthRequest> requestEntity = new HttpEntity<>(oathRequest, headers);
ResponseEntity<OauthResponse> result = restTemplate.exchange(oauthurl, HttpMethod.POST, requestEntity,
OauthResponse.class);
return result.getBody();
Is there any limitation on calling from RestTemplate rather than using OAuth2RestTemplate .My understanding is it will be achievable using RestTemplate also.Must i use OAuth2RestTemplate ?Any help?

RestTemplate does not set hostname in
headers.set("Host", hostname);
Adding below it worked
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");

Related

413 request entity too large issue in HTTP Get method call

Please don't mistake it as already asked question. The main difference here is, this issue is coming in Get method call. All the solutions discussed here or other places talks about either POST method or multipart form data.
Configuration I have provided is as below:
String url = env.getProperty(ApplicationConstants.PMCC_MANAGER_REGION_QUERY_URL);
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url).queryParam("inTIS_PMA_NUMBER","ALL");
URI uri = builder.build().toUri();
RestTemplate restTemplate = getRestTemplateBuilder().build();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
private RestTemplateBuilder getRestTemplateBuilder() {
Integer connectionTimeOut = 2000;
Integer readTimeOut = 3000;
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder();
restTemplateBuilder.setConnectTimeout(connectionTimeOut);
restTemplateBuilder.setReadTimeout(readTimeOut);
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setBufferRequestBody(false);
restTemplateBuilder.requestFactory(factory);
return restTemplateBuilder;
}
This code is part of Spring Boot application and deployed in WebLogic server.

RestTemplate call returns 401 Unauthorized

Background
I am trying to consume a REST endpoint hosted on IBM Cloud API from my SpringBoot application using RestTemplate. I am using the following snippet to make the call:
RestTemplate send = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setCacheControl(CacheControl.noCache());
headers.set("x-ibm-client-id", clientId);
headers.set("x-ibm-client-secret", clientSecret);
HttpEntity<BodyEntity> httpEntity = new HttpEntity<>(bodyEntity, headers);
send.exchange(ENDPOINT_URL, HttpMethod.POST, httpEntity, Object.class);
I used the following snippet to configure RestTemplate
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
Problem
Using this snippet, when the call is made I receive 401 Unauthorized. When I made the same call using Postman, I received correct response from server without any problem.
Since I received 401 response code I set to further investigate the request by logging headers and body and other parts of request.
I implemented ClientHttpRequestInterceptor to log outgoing requests to further debug the issue and added this interceptor to my RestTemplate config as follows:
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
// new code
builder.interceptors(new LoggingClientHttpRequestInterceptor());
return builder.build();
}
After making the request again, I could see in the log that the outgoing call contained all details as it should e.g. Headers and Body were correct.
After this, I changed the whole thing to use Apache HTTP Client as follows:
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(URL);
String reqString = "BODY";
httpPost.setEntity(new StringEntity(reqString, ContentType.APPLICATION_JSON));
httpPost.setHeader("accept", "application/json");
httpPost.setHeader("content-type", "application/json");
httpPost.setHeader("cache-control", "no-cache");
httpPost.setHeader("x-ibm-client-id", clientId);
httpPost.setHeader("x-ibm-client-secret", clientSecret);
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
System.out.println("Response status: " + response.getStatusLine());
HttpEntity entity1 = response.getEntity();
System.out.println("Response :" + entity1.toString());
} finally {
response.close();
}
Using the snippet above, I executed the request and received correct response.
Question
Why RestTemplate call returns and error whereas HttpClient returns correct response?
Do I need to further configure RestTemplate?
What have I missed?

Authentication for POST REST API with spring restTemplate

I want to use Spring RESTTemplate to post an Object to a web server and get one back.
Here the piece of code:
String authStringEncoded =
Base64.getEncoder().encodeToString
("582f3e4a9e933168ea1048e6:98c6f2736c5f02279d767ce7ddfe7e5d".getBytes("utf-8"));
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + authStringEncoded);
HttpEntity<String> request = new HttpEntity<String>(headers);
RestTemplate rt = new RestTemplate();
rt.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
rt.getMessageConverters().add(new StringHttpMessageConverter());
String uri = new String(REGISTERING_NEW_DEVICES.replace("{devicetype-id}", KIT_TYPE_ID));
TdkDevice deviceC3DF86B = new TdkDevice();
deviceC3DF86B.setId("C3DF86B");
deviceC3DF86B.setPal("44CFFFC9D5F8E8B2F36");
DeviceRegistration deviceRegistration = new DeviceRegistration();
deviceRegistration.getIds().add(deviceC3DF86B);
rt.postForObject(uri, HttpMethod.POST, request, deviceRegistration, DeviceRegistration.class);
But I got a compilation error:
The method postForObject(String, Object, Class<T>, Object...) in the type RestTemplate is not applicable for the arguments (String, HttpMethod, HttpEntity<String>, DeviceRegistration,
Class<DeviceRegistration>)
Your service call should be like following:
rt.postForObject(uri, request, DeviceRegistration.class);
According to spring RestTemplate api, postForObject method's parameters should be following:
Parameters:
url - the URL
request - the Object to be POSTed (may be null)
responseType - the type of the return value
uriVariables - the variables to expand the template
API Reference

Spring REST template - 401 Unauthorized error

I am using Spring Rest Template inside a Spring Boot Application.
I always get 401 Unauthorized error even though I am passing the credentials.
I am able to access this service by Chrome REST Web Service Client.
Is there a simplified way to access the REST template in SpringBoot.
Below is the code snippet done so far which results in 401 error
private DetailsBean invokeDetailsRestService(UserParam userParam){
ResponseEntity<DetailsBean> responseEntity = null;
String url = "https://dev.com/app/identifyuser/";
RestClientConfig restClientConfig =new RestClientConfig("user123","pass123");
responseEntity= restClientConfig.postForEntity(url, userParam, DetailsBean.class);
log.debug("User Details : {} ", responseEntity.getBody());
return responseEntity.getBody();
}
public ClientHttpRequestFactory getRequestFactory(String userName,String password){
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials( new AuthScope(null, -1), new UsernamePasswordCredentials(userName,password) );
HttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
RestClientConfig class
public RestClientConfig(String username, String password) {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(null, -1),
new UsernamePasswordCredentials(username, password));
HttpClient httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
}
Error:
WARN c7af55b5-1cac-4db6-a202-202416c27ba4
12612 --- [apr-8082-exec-8] o.a.http.impl.auth.HttpAuthenticator
: NEGOTIATE authentication error:
No valid credentials provided (Mechanism level:
No valid credentials provided (Mechanism level:
Failed to find any Kerberos tgt))
The authorization issue was fixed with the below code..
Credentials should be passed to a Spring REST Template with the below code:
String userAndPass = "Test:Test123";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
headers.add("Authorization", "Basic " + Base64Utility.encode(userAndPass.getBytes()));
I faced similar issue when i'm trying to make call to webservice, this solved my issue:
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("userName", "password"));
restTemplate.postForObject('','',''');
Pass the credentials like this, it should solve the issue.
I used spring boot 2.2.4.RELEASE version. then I work below way.
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(new BasicAuthenticationInterceptor(username, password));
RequestDto requestDto = new RequestDto();
// set parameter
ResponseDto response = restTemplate.postForObject(URL, requestDto, ResponseDto.class);
Or
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(username, password);
RequestDto requestDto = new RequestDto();
// set parameter
HttpEntity<RequestDto> request = new HttpEntity<>(requestDto, headers);
ResponseDto response = restTemplate.postForObject(URL, request, ResponseDto.class);

Spring RestTemplate redirect 302

I'm trying to use spring rest template to do a post request to login in.
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
LinkedMultiValueMap<String, Object> mvm = new LinkedMultiValueMap<String, Object>();
mvm.add("LoginForm_Login", "login");
mvm.add("LoginForm_Password", "password");
ResponseEntity<String> result = restTemplate.exchange(uriDWLogin, HttpMethod.POST, requestEntity, String.class);
My ResponseEntity status is 302, i want to follow this request to get the body response , because i didn't get the body for this request.
18:59:59.170 MAIN [http-nio-8080-exec-83] DEBUG c.d.s.c.DemandwareCtlr - loginToSandbox - StatusResponse - 302
18:59:59.170 MAIN [http-nio-8080-exec-83] DEBUG c.d.s.c.DemandwareCtlr - loginToSandbox - BodyResponse -
What can I do to solve this problem ?!
The redirection is followed automatically if the request is a GET request (see this answer). To make it happen on POST requests, one option might be to use a different request factory, like HttpComponentsClientHttpRequestFactory, and set it to use an HttpClient with the required settings to follow the redirect (see LaxRedirectStrategy):
final RestTemplate restTemplate = new RestTemplate();
final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
final HttpClient httpClient = HttpClientBuilder.create()
.setRedirectStrategy(new LaxRedirectStrategy())
.build();
factory.setHttpClient(httpClient);
restTemplate.setRequestFactory(factory);
I haven't tested, but this should work.

Resources