Can get from the response from Chrome, but when I want to get it with resttemplate it gives me 401 response.
I try to add the exact Content Types with rest template but it still gives the 401 error.
here is the request that i get it from Chrome :
GET URL HTTP/1.1
Host: host
Connection: keep-alive
Cache-Control: max-age=0
Authorization: Basic auth
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en,de;q=0.9,tr;q=0.8
and here is the code that i used in java to connect the service :
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_XML, MediaType.TEXT_HTML));
messageConverters.add(converter);
restTemplate.setMessageConverters(messageConverters);
HttpEntity<Map<String, String>> entity = new HttpEntity<>(params,createHeaders(username, password));
restTemplate.getForObject("URL",String.class, entity);
public static HttpHeaders createHeaders(String username, String password) {
String auth = username + ":" + password;
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")));
String authHeader = "Basic " + new String(encodedAuth);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Authorization", authHeader);
return httpHeaders;
}
It appears to be a problem with encoding the authorization token generation.
If you are sure about the username and password is correct, the only possibility is that the method/encoding used to generate the token is different on the browser(or the UI application which is generating the token) and the implementation of your createHeaders() method.
Please refer to the below links for more details:
What encoding should I use for HTTP Basic Authentication?
https://github.com/request/request/issues/1334
Hope it'll help.
Related
I'm developing an Android app that supposed to send PUT request to local server and when I try the same request using curl, I get success response, but from the Android app I get error with PUT request, here is the request for both from mobile app and curl, I listened to both requests on my PC using netcat
user#Laptop:~$ nc -l 192.168.1.104 55555
PUT /api/relay/0 HTTP/1.1
Host: 192.168.1.104:55555
User-Agent: curl/7.58.0
Accept: application/json
Content-Length: 31
Content-Type: application/x-www-form-urlencoded
apikey=2E5DE48567FB10F2&value=1
user#Laptop:~$ nc -l 192.168.1.104 55555
PUT /api/relay/0 HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
User-Agent: Dalvik/2.1.0 (Linux; U; Android 9; HRY-LX1MEB Build/HONORHRY-LX1MEB)
Host: 192.168.1.104:55555
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 31
apikey=2E5DE48567FB10F2&value=1
here is my android java request
public void jsonRequestVolley(int method, String url, String requestBody) {
RequestQueue queue = Volley.newRequestQueue(context);
JsonObjectRequest jsonRequest = new JsonObjectRequest(
method,
url,
requestBody,
successResponse(),
errorResponse()
)
{
/**
* Passing some request headers
* */
#Override
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
return headers;
}
};
queue.add(jsonRequest);
}
the working curl command is
curl -X PUT -H "Accept: application/json" http://192.168.1.105:55555/api/relay/0 --data "apikey=2E5DE48567FB10F2&value=1"```
I fixed the header because of local server requirements so, it worked now it look like
PUT /api/relay/0 HTTP/1.1
Accept: application/json
Content-Type: application/x-www-form-urlencoded
User-Agent: Dalvik/2.1.0 (Linux; U; Android 9; HRY-LX1MEB Build/HONORHRY-LX1MEB)
Host: 192.168.1.104:55555
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 31
I added the following to Android code
#Override
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
return headers;
}
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded";
}
all in request code.
I am trying to do a GET request with JAVA client using RestTemplate library, resulting in following error:
Exception in thread "main" org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden
When I am trying to hit the same URL by command line it is working fine. Posting the cURL command and Java code snippet here.
cURL :
curl -X GET -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json" https://xxxx-xxxx-xxxx {"key":"value"}
JAVA snippet :
String URL="https://xyz";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
//setting up the required headers
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.set("Authorization", "Bearer "+accessToken);
HttpEntity<String> entity = new HttpEntity<String>("body",headers);
//get request
ResponseEntity<String> responseEntity = restTemplate.exchange(URL, HttpMethod.GET, entity, String.class);
P.S - Is the issue because of the URL being a HTTPS one instead of HTTP ?
Add the user agent header, try and let us know if it works.
String URL="https://xyz";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
//setting up the required headers
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
//settting user agent
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.set("Authorization", "Bearer "+accessToken);
HttpEntity<String> entity = new HttpEntity<String>("body",headers);
//get request
ResponseEntity<String> responseEntity = restTemplate.exchange(URL, HttpMethod.GET, entity, String.class);
Trying to make a post call on one of our servers, but getting 400 BAD_REQUEST all the time
static void postUserToken()
{
final String url = "SERVER ADDRESS";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
MultiValueMap<String, String> requestBody= new LinkedMultiValueMap<>();
requestBody.add("userName", "TESTUSER");
requestBody.add("password", "TESTPASSWORD");
requestBody.add("auth", "secEnterprise");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class );
System.out.println(response);
}
get request to the same address works, post request via Postman works fine with the same body and headers
what am I missing ?
EDIT
calls from postman
POST /api/call/ HTTP/1.1
Host: SEREVERADDRESS:6405
Content-Type: application/json
Accept: application/json
User-Agent: PostmanRuntime/7.15.0
Cache-Control: no-cache
Postman-Token: token1,token2
Host: SEREVERADDRESS:6405
accept-encoding: gzip, deflate
content-length: 92
Connection: keep-alive
cache-control: no-cache
{
"password": "PASSWORD",
"auth": "secEnterprise",
"userName": "USER"
}
in response I get an object like this {"token":"longtoken"}
You are using a MultiValueMap however the json you send from postman looks like a simple Map.
This will produce {"key1":["val1"]} instead of {"key1":"val1"}
The problem might be in the
headers.setContentType(MediaType.APPLICATION_JSON);
Try using headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); or convert your data to a proper JSON.
More on this: https://www.baeldung.com/rest-template (4.4. Submit Form Data)
As far as I understand the problem and since I do not know your rest call details, I provide below the approach you can try.
Remove the following line.
requestBody.add("auth", "secEnterprise");
Add the line
headers.setHeader("auth", "secEnterprise");
If you are using other version of Apache Http Client, you can use the following code snippet.
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("header-name" , "header-value");
I'm trying to send a GET request with RestTemplate. My code looks like:-
RestTemplate template = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.add("_rToken", cookie.getValue());
String url = getUrl(contextUrl);
HttpEntity<Object> entity = new HttpEntity<Object>(headers);
ResponseEntity<String> response = null;
try {
response = template.exchange(url, HttpMethod.GET, entity, String.class);
}
catch(RestClientException ex) {
ex.printStackTrace();
}
return response;
On debugging, my URL looks good. What I have as entity is:-
body = null,
headers = <{Accept=[application/json],
user-agent=[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36],
_rToken=[2a6ac90f-1dfb-4df3-8d23-6d8d948fb9b5]}>
Since my get method doesn't take a parameter, body is supposed to be null. What am I doing wrong here?
Stack trace:
org.springframework.web.client.HttpClientErrorException: 403 null at
org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94)
at
org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:79)
at
org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at
org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:773)
at
org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:726)
at
org.springframework.web.client.RestTemplate.execute(RestTemplate.java:682)
at
org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:598)
at com.hm.ul.util.PlpUMCommunicator.get(PlpUMCommunicator.java:53)
I am trying to connect to an OAuth2 Server implementation using the following class (posting full for completeness):
import com.google.gwt.http.client.*;
import com.googlecode.gwt.crypto.bouncycastle.util.encoders.Base64;
import java.util.Map;
import java.util.function.Consumer;
public class HttpManager {
private static String toFormData(Map<String, String> data) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : data.entrySet())
sb.append("&")
.append(entry.getKey())
.append("=")
.append(entry.getValue());
sb.deleteCharAt(0);
return sb.toString();
}
public void postFormData(String url, Map<String, String> data, Consumer<Response> onSuccess, Consumer<Response> onFail) throws RequestException {
final String dataAsString = toFormData(data);
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, url);
builder.setHeader("Content-Type", "application/x-www-form-urlencoded");
builder.setHeader("Accept", "application/x-www-form-urlencoded");
builder.setHeader("Authorization", "Basic " + Base64.encode(("appId" + ":" + "oauthSecret").getBytes()));
builder.sendRequest(dataAsString, new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
if(response.getStatusCode() >= 400) {
onFail.accept(response);
} else {
onSuccess.accept(response);
}
}
#Override
public void onError(Request request, Throwable throwable) {
onFail.accept(null);
}
});
}
}
As you can see, I clearly append Content-Type, Accept and Authorization to the header. Further, I post along some data.
In reality though, the request looks like this:
OPTIONS /oauth/token HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://192.168.2.101:8888
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
Access-Control-Request-Headers: accept, authorization, content-type
Accept: */*
Referer: http://192.168.2.101:8888/demo.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
I wouldn't expect to see a request like this, given the above setup. What happened to my request headers? Also, there is no request body left, at all. And why is the request type Option? Can anybody shed some light?
This is due to the request being cross-origin, and what you're seeing is the preflight request in CORS parlance. It's the expected behavior, and the server has to authorize it with the appropriate response header.