Alternative of Basic Auth - Sonar Critical Vulnerability - java

I need to fetch the access token before making the actual call to the OAuth2-protected API.
As of now, I am doing it in the below fashion
String credential = clientId + ":" + clientSecret;
String encoding = Base64.getEncoder().encodeToString((credential).getBytes(‌"UTF‌​-8"​));
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Basic " + encoding);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("charset", "utf-8");
conn.setRequestProperty("Content-Length", Integer.toString(postDataLength));
Sonar says this is Non-Compliant RSPEC-2647, therefore I want to know what are the alternatives I can use, and how to fix this issue?
--EDIT
In the body, I was passing grant_type, username, and password.
I tried adding client_id and client_secret as well and it works.
Now I have one more question, is passing these credentials in the body more secure?
String body = "grant_type="+grantType+"&username="+username+"&password="+password+"&client_id="+clientId+"&client_secret="+clientSecret;
byte[] postData = body.getBytes(StandardCharsets.UTF_8);
int postDataLength = postData.length;
try(DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
wr.write(postData);
}
conn.connect();

Related

Java Rest : 400. The request is badly formed : URL contains -> api/Components(848569)/Properties('Stakeholder|Application Manager')

My URL is:
https://te.avolutionsoftware.com/api/Components(848569)/Properties('Stakeholder|Application Manager')
When i am using
allowMethods("PATCH");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
String auth = bearerToken;
//byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8));
String authHeaderValue = "Bearer " + new String(auth);
conn.setRequestProperty("Authorization", authHeaderValue);
//conn.setRequestProperty("X-HTTP-Method-Override", "PATCH");
conn.setRequestMethod(method);
conn.setRequestProperty("Content-Type", "application/json");
String input = data;//"{\"qty\":100,\"name\":\"iPad 4\"}";
conn.setDoOutput(true);
conn.setRequestProperty("Content-Length", String.valueOf(input.length()));
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
Always give
<HTML><HEAD><TITLE>Bad Request</TITLE><META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD><BODY><h2>Bad Request</h2><hr><p>HTTP Error 400. The request is badly formed.</p>
My JSON body:
{"Value": "Update Test"}
Same java method working fine for "POST" with different URL.
URL working fine in Postman with Patch and same Json Body String.
Any suggestion what could be issue here

How to hit the multiple url within same session and with one authentication in java

I have to hit one rest url and before that i am hitting another rest url for loginn purposes by passing username/password. I am getting 200 OK from the first url. Now when i am trying to consume another REST url it's giving me 401 error.Code is as follows"
String urlParameters = "username=a&password=b&rememberme=false";
byte[] postData = urlParameters.getBytes( StandardCharsets.UTF_8 );
int postDataLength = postData.length;
URL url = new URL("myloginurl");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("charset", "UTF-8");
con.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));
con.setUseCaches( false );
try( DataOutputStream wr = new DataOutputStream( con.getOutputStream())) {
wr.write( postData );
}
int respCode = con.getResponseCode();
if(respCode==200){
urlParameters = "id=x&col1=y&op1=z&val1=t";
postData = urlParameters.getBytes( StandardCharsets.UTF_8 );
postDataLength = postData.length;
url = new URL("myanotherurl");
con.setDoOutput(true);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("charset", "UTF-8");
con.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));
con.setUseCaches( false );
try( DataOutputStream wr = new DataOutputStream( con.getOutputStream())) {
wr.write( postData );
}
System.out.println(con.getResponseCode());
}
Can anybody please point out where i am doing the mistake. Also let me know is there any better way to write this code.
Thanks
The server should return a session id in the form of a new cookie in your first request. You have to include that cookie in your second request, so that the server can identify you. The cookie is sent within the http headers.
After you get the responsecode from the first request, you can fetch the new cookie values like:
String cookieValue = con.getHeaderFields()
.getOrDefault("Set-Cookie", Collections.emptyList())
.stream()
.map(str -> str.split(";")[0])
.collect(joining("; "));
Then you use that value for the cookies in the next request like:
con.setRequestProperty("Cookie", cookieValue);

Why android is not posting full email on the server using HttpURLConnection and POST method?

I am trying to post data on my server using HttpURLConnection and POST method in android. Here is my android code
String urlParameters = URLEncoder.encode("email", "UTF-8") + "=" +
URLEncoder.encode(email, "UTF-8");
byte[] postData = urlParameters.getBytes( "UTF-8" );
int postDataLength = postData.length;
//System.out.println(email);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setChunkedStreamingMode(0);
urlConnection.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded");
urlConnection.setRequestProperty( "charset", "utf-8");
urlConnection.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));
urlConnection.setUseCaches( false );
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
wr.write( postData );
wr.close();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
In this code where I am printing email it shows me the correct full email abc#xyz.com but when I receive it on my server it is not full email.
I am using pyhton and django for my website. When I am printing my post data on server it is giving me this result,
<QueryDict: {'1e\r\nemail': ['abc#xyz']}>
And if you notice, I am receiving 1e and some times 1c in the key instead of only email. So can anyone tell me what is wrong with my codes? Or why I am receiving this data?
Your Android code looks ok. But give it a try without that chunked streaming mode and set caches lines.

HTTPS Login using Java

I've a problem to login to a website via https.
I wrote this code (it works) for http access:
String user = user;
String password = psw;
String authString = user + ":" + password;
byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
String authStringEnc = new String(authEncBytes);
URLConnection connection= url.openConnection();
connection.setRequestProperty("Authorization", "Basic " + authStringEnc);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
connection.connect();
I'd like to do the same things but via https. Is it possible?
You can, please use HttpsURLConnection
Checkout sample program on http://www.mkyong.com/java/java-https-client-httpsurlconnection-example/
When specifying your URL, make sure to pass "https://..."
url.openConnection();
will return you an object that has the type of the established connection. It will always be URLConnection, but it can be a class that extends URLConnection as well. Such classes are HttpURLConnection and HttpsURLConnection (and others).
You should verify that the returned object is of type HttpsURLConnection. And if it's not, you should stop the connection (in case you want to avoid non secure connections).
if (connection instanceof HttpsURLConnection)

How to send requestparameter in POST request using HttpUrlConnection

I need to send a POST request to a URL and send some request parameters. I am using HttpURLConnectionAPI for this. But my problem is I do not get any request parameter in the servlet. Although I see that the params are present in the request body, when I print the request body using request.getReader. Following is the client side code. Can any body please specify if this is correct way to send request parameters in POST request?
String urlstr = "http://serverAddress/webappname/TestServlet";
String params = "&paramname=paramvalue";
URL url = new URL(urlstr);
HttpURLConnection urlconn = (HttpURLConnection) url.openConnection();
urlconn.setDoInput(true);
urlconn.setDoOutput(true);
urlconn.setRequestMethod("POST");
urlconn.setRequestProperty("Content-Type", "text/xml");
urlconn.setRequestProperty("Content-Length", String.valueOf(params.getBytes().length));
urlconn.setRequestProperty("Content-Language", "en-US");
OutputStream os = urlconn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(params);
writer.close();
os.close();
To be cleaner, you can encode to send the values.
String data = URLEncoder.encode("key1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8");
data += "&" + URLEncoder.encode("key2", "UTF-8") + "=" + URLEncoder.encode("value2", "UTF-8");
URL url = new URL("http://yourserver.com/whatever");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
Like #Kal said, get rid of the leading & and don't bother with the BufferedWriter. This works for me:
byte[] bytes = parameters.getBytes("UTF-8");
httpUrlConnection.setRequestProperty("Content-Length", String.valueOf(bytes.length));
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setDoOutput(true);
httpUrlConnection.connect();
outputStream = httpUrlConnection.getOutputStream();
outputStream.write(bytes);

Categories

Resources