Explination
I am working on a Java App that sends a text message via a CPAS API (Similar to Tweepy). I am using CURL to request the message send. The request from Java seems to be sent but I am getting a 401 code. I'm assuming there is an issue with the encoding of my Authentication for the request. The code is as follows:
URL url = new URL("https://api.zang.io/v2/Accounts/ACe1889084d37de951ef064200aecbe4b2/SMS/Messages");
String auth = AUTH + ":" + TOKEN;
String encodeedAuth = Base64.getEncoder().withoutPadding().encodeToString(auth.getBytes());
HttpURLConnection http = (HttpURLConnection)url.openConnection();
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
http.setRequestProperty("Authorization", "Basic " + encodeedAuth);
String data = "From=+14132698029&To=17817381451&Body=New Test";
byte[] out = data.getBytes(StandardCharsets.UTF_8);
OutputStream stream = http.getOutputStream();
stream.write(out);
System.out.println(http.getResponseCode() + " " + http.getResponseMessage());
http.disconnect();
"""
An HTTP 401 response is commonly an HTTP endpoint authorization failure. The best way to see why your auth credentials are failing is to capture the request/response pair in transit (at the receiving end would be optimal) and then compare that request/response pair to one that works.
Related
I want to consume rest api from url with http basic authentication that returns a big json & then i want to parse that json without POJO to get some values out of it. How can i achieve that in java spring?
I know this is common question but i could not get proper solution that worked for me.
Please help me someone.
Using the Apache HttpClient, the following Client Code snipped has been copied from the following URL. The comments have been added by myself.
https://www.baeldung.com/httpclient-4-basic-authentication
HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
// Combine the user and password pair into the right format
String auth = DEFAULT_USER + ":" + DEFAULT_PASS;
// Encode the user-password pair string in Base64
byte[] encodedAuth = Base64.encodeBase64(
auth.getBytes(StandardCharsets.ISO_8859_1));
// Build the header String "Basic [Base64 encoded String]"
String authHeader = "Basic " + new String(encodedAuth);
// Set the created header string as actual header in your request
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
I'm posting to an API server and I'm getting the following reply:
Server Response: {"detail":"Authentication credentials were not provided."}
I'm writing the requests in Java and I'm not sure exactly why it's saying credentials were not provided.
Here is a snippet of my code:
hconn.setRequestProperty("Content-Type", "application/json");
hconn.setRequestProperty( "Accept", "application/json" );
if( urlconn instanceof HttpsURLConnection )
{
String encoded = new String(Base64.getEncoder().encode( ( username + ":" + password).getBytes()));
String auth = "Basic " + encoded;
urlconn.setRequestProperty("Encoded Authorization", auth );
}
Where hconn is of type HttpURLConnection
This is the only relvant snippet that you guys need. Are there properties i'm missing to set here?
I know the server response is from a Django framework but the documentation is not clear on spotting what IS required to prevent this.
Any help appreciated.
Authorization is the correct request header name and not 'Encoded Authorization'. So, you should set
urlConn.setRequestProperty("Authorization", auth);
I am using Restful Services on server and trying to maintain the same session after performing login:
URL endpoint = new URL(getString(R.string.url_login));
// Create connection
HttpURLConnection myConnection = (HttpURLConnection) endpoint.openConnection();
myConnection.setRequestMethod("POST");
myConnection.setRequestProperty("User-Agent", "my-rest-app-v0.1");
// Create the data
String myData = "username=" + username + "&password=" + pwd;
// Enable data writing
myConnection.setDoOutput(true);
// Write the data
myConnection.getOutputStream().write(myData.getBytes());
rc = myConnection.getResponseCode();
if (rc == 200) {
String Cookie= myConnection.getHeaderField("Set-Cookie");
URL endpoint2 = new URL(getString(R.string.url_checkUserType));
HttpURLConnection myConnection2 =
(HttpURLConnection)endpoint2.openConnection();
myConnection2.setRequestMethod("GET");
myConnection2.setRequestProperty("User-Agent", "my-rest-app-v0.1");
myConnection2.setRequestProperty("Cookie", Cookie);
rc2 = myConnection2.getResponseCode();
....
}....
The problem is that rc2 is every time 401 as WebService doesn't recognize that requiest is part of the same session. What am I doing wrong?
You may do as follows
on the server side, it checks if the incoming request has a "sessionId" in cookie: if not, create one and return it in response; if yes, it knows the request belongs to a known session
on the client side, after a successful login, retrieve the "sessionId" from the response, and set it in the following requests
==
connection.setRequestProperty("Cookie", "JSESSIONID=" + URLEncoder.encode(jSessionId, "UTF-8"));
The solution was to use Spring RESTful services for Android that worked great for me.
I'm working on a program that queries Google Safe Browsing for certain urls, but I'm getting an error that I don't think I should be getting.
I'm sending the following request:
2
http://google.com
http://facebook.com
via POST to: https://sb-ssl.google.com/safebrowsing/api/lookup?client=api&apikey=[KEY]&appver=1.5.2&pver=3.1
However, I'm getting a 403 response.
This is what the documentation says for HTTP POST lookup errors:
The server generates the following HTTP error codes for the POST request:
•200: AT LEAST ONE of the queried URLs are matched in either the phishing, malware, or unwanted software lists. The actual results are returned through the response body.
•204: NONE of the queried URLs matched the phishing, malware, or unwanted software lists, and no response body is returned.
•400: Bad Request—The HTTP request was not correctly formed.
•401: Not Authorized—The API key is not authorized.
•503: Service Unavailable—The server cannot handle the request. Besides the normal server failures, this could also indicate that the client has been “throttled” for sending too many requests.
The response code 403 isn't listed, yet I'm getting it.
I have triple-checked my API-key and made sure the API is enabled for my project. I'm using a Server-key, but I also tried a Browser-key.
I tried doing a GET request also, and that did work, but I cannot get POST to work. What's going on?
Here is my code:
try {
String baseURL="https://sb-ssl.google.com/safebrowsing/api/lookup";
String arguments = "";
arguments +=URLEncoder.encode("client", "UTF-8") + "=" + URLEncoder.encode("api", "UTF-8") + "&";
arguments +=URLEncoder.encode("apikey", "UTF-8") + "=" + URLEncoder.encode("[KEY]", "UTF-8") + "&";
arguments +=URLEncoder.encode("appver", "UTF-8") + "=" + URLEncoder.encode("1.5.2", "UTF-8") + "&";
arguments +=URLEncoder.encode("pver", "UTF-8") + "=" + URLEncoder.encode("3.1", "UTF-8");
// Construct the url object representing cgi script
URL url = new URL(baseURL + "?" + arguments);
// Get a URLConnection object, to write to POST method
HttpURLConnection connect = (HttpURLConnection) url.openConnection();
connect.setRequestMethod("POST");
// Specify connection settings
connect.setDoInput(true);
connect.setDoOutput(true);
// Get an output stream for writing
OutputStream output = connect.getOutputStream();
PrintStream pout = new PrintStream (output);
pout.print("2");
pout.println();
pout.print("http://www.google.com");
pout.println();
pout.print("http://www.facebook.com");
pout.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connect.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println("w: " + decodedString);
}
in.close();
} catch(Exception e) {
e.printStackTrace();
}
I found the error. The CGI parameter was incorrect. It should have been key and not apikey. Still weird that you get an undocumented response-code though.
I am doing authentication and receiving a null cookie. I want to store this cookie but sever is not returning me a cookie. But the response code is 200 ok.
httpConn.setRequestProperty(
"Authorization",
"Basic " + Base64OutputStream.encodeAsString(
login.getBytes(), 0, login.getBytes().length, false, false));
String tmpCookie = httpConn.getHeaderField("set-cookie");
This is my code.
String login = username + ":" + password;
String base = "http://mysever/login";
HttpConnection httpConn = null;
httpConn = (HttpConnection)Connector.open(base);
// Setup HTTP Request to POST
httpConn.setRequestMethod(HttpsConnection.POST);
httpConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
httpConn.setRequestProperty("Accept",
"text/html,application/xhtml+xml,application/xml,application/x-javascript,*/*;q=0.5 ");
//Add the authorized header.
httpConn.setRequestProperty("Authorization",
"Basic " + Base64OutputStream.encodeAsString(
login.getBytes(), 0, login.getBytes().length, false, false));
message = httpConn.getResponseMessage();
status = httpConn.getResponseCode();
tmpCookie = httpConn.getHeaderField("Set-Cookie");
EventLogger.logEvent(guid, status);
if (status == HttpConnection.HTTP_OK)
{
String tmpCookie = httpConn.getHeaderField("set-cookie");
authForm.append("\nConnected");
authForm.append("\n\nLogin Response:" + message +
"\nHTTP response code:" + status + "\nCookie: "
+ tmpCookie);
//getNewZipFile();
}
else if(status !=HttpConnection.HTTP_OK){
throw new IOException("HTTP response code: " + status);
}
httpConn.close();
Have you actually made a connection? Your code shows you setting a request property and then immediately trying to find a header value, with no indication that the request has actually been sent.
If you are doing so (in which case fuller code would be welcome) you should use Wireshark or something similar to find out what the network traffic actually looks like.
How request Authorization header connected with response Cookie?
I suppose that it is in no way.
May be server doesn't return any cookies? Or may be "set-cookie" is case sensitive, and you must use "Set-Cookie" instead.