2-way mutual negotiation in java client app - java

I am trying to create java desktop app for online shopping. So far I am able to login, select product, and select check out
using httpsurlconnect. but after checkout site redirects to bank payment gateway. And i always get response unable to process your request after redirect.
I think this is because payment gateway uses 2-way mutual negotiation (not sure). So how can i create 2-way mutual negotiation on fourth request.
I have done a bit research on internet. i found that it requires keystore.jks and truststore.jks. I asume that JDK comes with CA truststore which can accept server certificate.
I need keystore.jks file with client key and certificate. if i create self signed cert, will the server accept it. Server users verisigned CA cert and i have no control over server.
How can i get client keystore.jks and implement handshake on fourth request. Sample code of my implementaion is given below.
public void query(){
//request 1
String url_1 = "https://www.shop.com/login.do";
String ref_1 = "https://www.shop.com/";
Map<String, String> post = new HashMap<String, String>();
post.put("userName", var.userName);
post.put("password", var.password);
String new_post_1 = Generate_post(post);
Connect(url_1, ref_1, new_post_1);
//request 2
String url_2 = "https://www.shop.com/select_product.do";
String ref_2 = "https://www.shop.com/login.do";
Map<String, String> post = new HashMap<String, String>();
post.put("product", var.Name);
post.put("id", var.id);
post.put("price", var.price);
String new_post_2 = Generate_post(post);
Connect(url_2, ref_2, new_post_2);
//request 3
String url_3 = "https://www.shop.com/checkout.do";
String ref_3 = "https://www.shop.com/select_product.do";
Map<String, String> post = new HashMap<String, String>();
post.put("product", var.Name);
post.put("id", var.id);
post.put("total_price", var.total_price);
post.put("checkout", var.checkout);
String new_post_3 = Generate_post(post);
Connect(url_3, ref_3, new_post_3);
//request 4
String url_4 = "https://secure.payment.com/gateway.do";
String ref_4 = "https://www.shop.com/checkout.do";
Map<String, String> post = new HashMap<String, String>();
post.put("total_price", var.total_price);
post.put("bank", var.bank);
post.put("confirm", var.confirm);
String new_post_4 = Generate_post(post);
Connect(url_4, ref_4, new_post_4);
}
Connnect method:
void Connect(String https_url, String referal, String query) throws IOException{
URL url = new URL(https_url);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
//set properties
HttpsURLConnection.setFollowRedirects(true);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestMethod("POST");
con.setUseCaches(false);
con.setAllowUserInteraction(false);
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0");
con.setRequestProperty("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
con.setRequestProperty("Accept-Language","en-us,en;q=0.5");
con.setRequestProperty("Connection","keep-alive");
con.setRequestProperty("charset","iso-8859-1");
con.setRequestProperty("Referer",referal);
con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
con.setRequestProperty("Content-Length",String.valueOf(query.length()));
// Create Output streams
BufferedWriter outStream = new BufferedWriter(new OutputStreamWriter(con.getOutputStream()));
outStream.write(query);
outStream.flush();
outStream.close();
if(con.getResponseCode()==HttpsURLConnection.HTTP_OK ){
// Create Input streams
InputStreamReader in = new InputStreamReader(con.getInputStream());
BufferedReader inStream = new BufferedReader(in, 1024*24);
String html;
StringBuffer page = new StringBuffer();
while((html = inStream.readLine()) != null) {
page.append(html+"\n"); }
inStream.close();
}else{
System.out.println(con.getHeaderFields());
InputStreamReader in = new InputStreamReader(con.getErrorStream());
BufferedReader inStream = new BufferedReader(in);
String html;
StringBuffer page = new StringBuffer();
while((html = inStream.readLine()) != null) {
page.append(html+"\n"); }
}
con.disconnect();
}

Related

java how to force refresh on url connection

I am behind proxy server and I am using the following code to get data from url:
private static String getData(String address)throws Exception
{
System.setProperty("java.net.useSystemProxies","true");
Date d = new Date();
String finalAdress = address+"?x="+d.getTime();
URL url = new URL(finalAdress);
System.out.println(finalAdress);
InputStream html = null;
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
con.setUseCaches(false);
con.setDefaultUseCaches(false);
con.setRequestMethod("GET");
con.addRequestProperty("Cache-Control", "no-cache");
//con.addRequestProperty("Cache-Control", "max-age=0");
con.addRequestProperty("Expires", "0");
con.addRequestProperty("Pragma", "no-cache");
html = con.getInputStream();
//html = url.openStream();
int c = 0;
StringBuffer buffer = new StringBuffer("");
while(c != -1) {
c = html.read();
buffer.append((char)c);
}
return buffer.toString();
}
However when data changes on the server side - I sill for some time get the same old (cached) data as a response..
Tried to use:
-Cache-Control
-slightly modified urls address+"?x="+d.getTime();
but nothing seems to work.
Is there a way to force refresh as I would with a web browser (ctrl-F5) ?

How to browse many urls with one httpURLConnection in java

I'm trying to connect to a website and to send many different post requests through different pages all over the website.
I've reached the first step:connect the website.
But now, I need to change the request url and keeping the same httpURLConnection.
For now my code is:
//openning the connection to the website
URL url = new URL("http://path/to/the/website");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
//preparing the post arguments
Map<String, Object> params = new HashMap<>();
params.put("Action", "connect_user");
params.put("login", "login");
params.put("password", "password");
StringBuilder sb = new StringBuilder();
for (Entry<String, Object> e : params.entrySet()) {
if (sb.length() != 0)
sb.append('&');
sb.append(URLEncoder.encode(e.getKey(), "UTF-8"));
sb.append('=');
sb.append(URLEncoder.encode(String.valueOf(e.getValue()), "UTF-8"));
}
//writing the request and sending
BufferedOutputStream writer = new BufferedOutputStream(conn.getOutputStream());
writer.write(sb.toString().getBytes(Charset.forName("UTF-8")));
writer.flush();
At this step i'm connected and sucessfully logged in.
What I need to do now is to redirect the same connection to a second url.
Thanks.

Accessing Google oAuth giving invalid grant_type (Bad request)

I searched a lot in SO, skim through many questions regarding the same error, applied whatever they suggested, but nothing turned out. Hence writing here.
I am learning how to make a call to Google API (say Google Calendar API). I am going through the google developers tutorial from
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
So I have created a service account in the google, created credentials (I want to invoke Google API from my own application). After then I create JWT, singed my JWT with private key shared by google, and making a REST POST call to get the oAuth. Here is my code
public class TestGoogleAPI {
public static void main(String[] args) throws Exception{
String header = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}";
long time = Calendar.getInstance().getTimeInMillis()/1000;
String claimSet = "{\"iss\":\"xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\"," +
"\"scope\":\"https://www.googleapis.com/auth/calendar\"," +
"\"aud\":\"https://www.googleapis.com/oauth2/v3/token\"," +
"\"exp\":"+ (time+3600) +"," +
"\"iat\":" + time +"}";
String base64Header = new String(Base64.encodeBase64(header.getBytes()),"UTF-8");
String base64ClaimSet = new String(Base64.encodeBase64(claimSet.getBytes()),"UTF-8");
String input = base64Header + "." + base64ClaimSet;
File f = new File("D:/downloads/privatekey.txt");
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int)f.length()];
dis.readFully(keyBytes);
dis.close();
byte[] key = Base64.decodeBase64(keyBytes);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(key);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privatekey = kf.generatePrivate(spec);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privatekey);
signature.update(input.getBytes());
String base64Sign = new String(Base64.encodeBase64(signature.sign()),"UTF-8");
doHttpPost("https://www.googleapis.com/oauth2/v3/token", input + "." + base64Sign);
}
public static void doHttpPost(String urlStr, String assertion) throws Exception{
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
OutputStream out = conn.getOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
writer.write("grant_type");
writer.write("=");
writer.write(URLEncoder.encode("urn:ietf:params:oauth:grant-type:jwt-bearer", "UTF-8"));
writer.write("&");
writer.write("assertion");
writer.write("=");
writer.write(URLEncoder.encode(assertion, "UTF-8"));
writer.close();
out.close();
if (conn.getResponseCode() != 200) {
System.out.println(conn.getResponseMessage());
}
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
conn.disconnect();
System.out.println(sb.toString());
}
}
I am getting 400 (Bad request). I tried the same from "Chrome's Advanced Rest Client", but the result is same, invalid grant_type (Bad request).
{
error: "invalid_grant"
error_description: "Bad Request"
}
Am I missing any thing here. Please help me
Thanks
Finally I got the resolution. When I am encoding header and claimset, I am doing base64 encoding, instead of base64safeURL encoidng. After replacing
Base64.encodeBase64(some_data);
with
Base64.encodeBase64URLSafe(some_data);
at all occurrences in the above code, everything is working fine. I am getting the access token and able to hit the google API with oAuth token

Java alternative for curl -T

i must send one text string using java to a IP web cam, before it take picture. So after I read the camera user manual and searched in google, the only thing i found was using cURL. I install it and its run fine, and everything is okay, the text from the file appear in the video streaming. The command is this
curl -T test.xml http://admin:pass#192.168.0.1/Video/inputs/channels/2/overlays/text/2
and the content of test.xml is:
<TextOverlay xmlns="http://www.hikvision.com/ver10/XMLSchema" version="1.0">
<id>2</id>
<enabled>true</enabled>
<posX>5</posX>
<posY>5</posY>
<message>Text here </message>
</TextOverlay>
So I want to send this content using Java, I already tried using post and java.net but I get an error "Server returned HTTP response code: 403 for URL"
Here is my code:
System.out.println("Starting......");
URL url = new URL("http://192.168.0.1/Video/inputs/channels/2/overlays/text/2/");
String data = "<TextOverlay xmlns=\"http://www.hikvision.com/ver10/XMLSchema\" version=\"1.0\">\n"
+ "<id>2</id>\n"
+ "<enabled>true</enabled>\n"
+ "<posX>5</posX>\n"
+ "<posY>5</posY>\n"
+ "<message>Text here</message>\n"
+ "</TextOverlay>";
HttpURLConnection httpConnection = prepareConn(url, null, "admin", "pass");
httpConnection.setDoOutput(true);
httpConnection.setDoInput(true);
httpConnection.setRequestMethod("POST");
httpConnection.setRequestProperty ( "Content-Type", "text/xml" );
OutputStreamWriter out = new OutputStreamWriter(httpConnection.getOutputStream());
out.write(data);
out.flush();
out.close();
System.out.println("Printing......");
System.out.println(httpConnection.getResponseCode());
System.out.println(httpConnection.getResponseMessage());
InputStreamReader reader = new InputStreamReader(httpConnection.getInputStream());
StringBuilder buf = new StringBuilder();
char[] cbuf = new char[2048];
int num;
while(-1 != (num = reader.read(cbuf)))
{
buf.append(cbuf, 0, num);
}
String result = buf.toString();
System.out.println("\nResponse received from server after POST" + result);
}
static private HttpURLConnection prepareConn(final URL url, Properties request_props, String username, String password) throws Error, IOException
{
System.out.println("Authorization......");
if (!url.getProtocol().equalsIgnoreCase("http"))
throw new Error(url.toString() + " is not HTTP!");
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(300);
conn.setRequestMethod("POST");
final Properties DEFAULT_REQUEST_PROPS = new Properties();
DEFAULT_REQUEST_PROPS.setProperty("charset", "utf-8");
final Properties props = new Properties(DEFAULT_REQUEST_PROPS);
if (request_props != null)
for (final String name : request_props.stringPropertyNames())
props.setProperty(name, request_props.getProperty(name));
for (final String name : props.stringPropertyNames())
conn.setRequestProperty(name, props.getProperty(name));
if(null != username && null != password)
conn.setRequestProperty("Authorization", "Basic " + new BASE64Encoder().encode((username+":"+password).getBytes()));
return conn;
}
Hope someone can help :)
All the best !
I just use wrong RequestMethod, after deep research I found that i must use PUT not POST request. Now just change setRequestMethod("POST") to setRequestMethod("PUT") and works like a charm.

Keywords object is empty when making authenticated YouTube API call with Java YouTubeService class

I am trying to fetch videos from MY OWN YouTube account, so that I get the keywords/tags for each video. I'm trying to use the most simple approach for making an authenticated call to get my videos with keywords/tags.
Here is my Java code:
String clientID = "XXXXXXXXXXXX.apps.googleusercontent.com";
String devKey = "MY-DEVELOPER-KEY";
String userEmail = "MY-GMAIL-EMAIL";
String userPassword = "MY-GMAIL-PASSWORD";
String authorName = "MY-YOUTUBE-ACCOUNT-NAME";
String url = "https://gdata.youtube.com/feeds/api/videos";
YouTubeService service = new YouTubeService( clientID, devKey );
service.setUserCredentials( userEmail, userPassword );
YouTubeQuery query = new YouTubeQuery( new URL( url ) );
query.setAuthor( authorName );
VideoFeed videoFeed = service.query( query, VideoFeed.class );
Please, help me understand what I am doing wrong, to authenticate and get those media keywords.
If you are going to refer me to another authentication option, please, show an example of using that other option for my specific scenario.
You're running into the behavior described in this blog post: your API calls are going against the search index, and those results will never have the keywords in them.
There's an example that shows how you could request the uploads feed in Java using v2 of the Data API; you can modify that example to use the channel name default instead of username and you'll automatically pull in the uploads feed for the currently authenticated account.
Here is what finally worked for me to get JSON-C feed with tags (keywords):
/** AUTHENITICATION **/
// HTTP connection
URL url = new URL("https://www.google.com/accounts/ClientLogin");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
// Form the POST parameters
StringBuilder content = new StringBuilder();
content.append("Email=").append(URLEncoder.encode("MY-GMAIL-LOGIN", "UTF-8"));
content.append("&Passwd=").append(URLEncoder.encode("MY-GMAIL-PASSWORD", "UTF-8"));
content.append("&service=").append(URLEncoder.encode("youtube", "UTF-8"));
OutputStream outputStream = urlConnection.getOutputStream();
outputStream.write(content.toString().getBytes("UTF-8"));
outputStream.close();
// Check response status
int responseCode = urlConnection.getResponseCode();
if( responseCode != HttpURLConnection.HTTP_OK ) {
// EXCEPTION
}
// Get the token from the response
String token;
InputStream inputStream = urlConnection.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while((line = in.readLine()) != null) {
if ( line.indexOf("Auth=") > -1 ) {
token = line.split("=")[1];
}
}
/** JSON-C FEED WITH TAGS **/
HttpClient client = new HttpClient();
GetMethod method = new GetMethod("http://gdata.youtube.com/feeds/api/users/default/uploads?v=2&alt=jsonc&max-results=50&start-index=1");
// set the authentication headers
method.setRequestHeader("Authorization", "GoogleLogin auth=" + token);
method.setRequestHeader("X-GData-Key", "key=MY-DEV-KEY");
method.setRequestHeader("GData-Version", "2");
method.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
// Make the call
int statusCode = client.executeMethod(method);
if ( statusCode != HttpStatus.SC_OK ) {
// EXCEPTION
}
String JSON = method.getResponseBodyAsString();

Categories