When I am sending POST request to an url with authentication from GAE, I am getting MalformedURLException on urlConn.getResponseCode() function.
This problem arises only on the deployment server and does not arise when I run the code on local server.
Invalid URL specified: https://user:passtoken#twilix.exotel.in/v1/Accounts/user/Sms/send
java.net.MalformedURLException: Invalid URL specified: https://user:passtoken#twilix.exotel.in/v1/Accounts/user/Sms/send
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.convertApplicationException(URLFetchServiceImpl.java:120)
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:43)
at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.fetchResponse(URLFetchServiceStreamHandler.java:417)
at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.getInputStream(URLFetchServiceStreamHandler.java:296)
My code:
String urlString =
"https://user:passtoken#twilix.exotel.in/v1/Accounts/user/Sms/send";
URL url = new URL(urlString.toString());
String userpass = "user:passtoken";
String basicAuth = "Basic " +
javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes());
urlConn = (HttpURLConnection) url.openConnection();
urlConn.setRequestMethod("POST");
urlConn.setRequestProperty ("Authorization", basicAuth);
urlConn.connect();
responseCode = urlConn.getResponseCode(); //Throws Exception
Everything works fine when I try to set my url as https://httpbin.org/post
Is this a bug of GAE or some problem with my code?
It looks like the problem is with the ampersand symbol. Since you are already putting the credentials in the HTTP Request, they should not be needed in the URL as well. Try changing the first line to this instead.
String urlString = "https://twilix.exotel.in/v1/Accounts/user/Sms/send";
Related
I was trying to make Jira cloud rest api call using JWT authentication.
I've followed the steps found in atlassian documentation but I've got this exception:
com.atlassian.jwt.exception.JwtInvalidClaimException: Expecting claim 'qsh' to have value 'qsh value' but instead it has the value 'qsh value'
Thanks in advance
Here is the answer
//1-First we need to create the qsh 'Query String Hash'
String httpMethod = "GET";
String restApiPath = "rest api url without the base url";
String urlParameters = "key=value&key1=value1";
String qsh = String.format("%s%s%s%s%s", httpMethod, "&", restApiPath, "&", urlParameters);
//2-Encode qsh
String encodedQsh = JwtUtil.computeSha256Hash(qsh);
//3-Create JwtJsonBuilder
JwtJsonBuilder jwtJsonBuilder = new JsonSmartJwtJsonBuilder();
jwtJsonBuilder.issuedAt(issuedAt);
jwtJsonBuilder.expirationTime(expiresAt);
jwtJsonBuilder.issuer(issuer);
jwtJsonBuilder.subject(subject);
jwtJsonBuilder.type("JWT");
jwtJsonBuilder.queryHash(encodedQsh);
//4-Encode JWT token
String encodedJwt = new NimbusJwtWriterFactory().macSigningWriter(SigningAlgorithm.HS256, "shared-secret- value").jsonToJwt(jwtJsonBuilder.build());
//5-Build your URL
String urlStrg = baseUrl + restApiPath + "?" + urlParameters
//6-Open Url Connection
URL url = new URL(urlStrg);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Accept", "application/json");
httpURLConnection.setRequestProperty("Authorization", "JWT " + encodedJwtToken);
httpURLConnection.setRequestMethod(httpMethod);
int responseCode = httpURLConnection.getResponseCode();
//responseCode to check if the request is valid and authenticated
I'm trying to get a redirected URL from newURLConnection, but when I print out, it still outputs what the URL is before it is redirected. I'm certain that the original newURLConnection is a legitimate URL because when I enter it into a web browser it redirects automatically. I've tried it with conn.setInstanceFollowRedirects set to both false and true, and neither works...for some reason it's just impossible for me to get the redirected URL. Help would definitely be appreciated.
//open a connection
URLConnection newURLConnection = params[0].openConnection();
HttpURLConnection conn = (HttpURLConnection) newURLConnection;
//following code sourced from mkyong.com
conn.setInstanceFollowRedirects(true);
//HttpURLConnection.setFollowRedirects(true);
conn.connect();
//get the redirected URL
InputStream newURLConnectedStream = conn.getInputStream();
System.out.println("" + conn.getURL());
Try the following code to get it,
URL url = new URL(url);
HttpURLConnection ucon = (HttpURLConnection) url.openConnection();
ucon.setInstanceFollowRedirects(false);
URL secondURL = new URL(ucon.getHeaderField("Location"));
URLConnection conn = secondURL.openConnection();
Copied from java, android, resolve an url, get redirected uri
Java project (Eclipse). Sandbox test app. I got all necessary token and secret pairs using the Sample OAuth app and assigned them to String variables: consumerKey, consumerSecret, accessToken, accessTokenSecret, appToken, companyID.
Next. I tried to authorize QBO in two different ways: directly with HTTP connection (try/catch blocks removed):
OAuthConsumer ouathconsumer = new DefaultOAuthConsumer(consumerKey,consumerSecret);
ouathconsumer.setTokenWithSecret(accessToken, accessTokenSecret);
HttpURLConnection urlConnection = null;
URL url = new URL("https://sandbox-quickbooks.api.intuit.com/v3/company/" + companyID + "/customer/4");
urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setUseCaches(false);
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Connection", "Close");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
ouathconsumer.sign(urlConnection);
urlConnection.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
System.out.println(rd.readLine());
rd.close();
And it works well! But I wanna do the SDK calls. Following source gives me error (try/catch removed, secret strings are the same):
IAuthorizer authorizer = new OAuthAuthorizer(consumerKey, consumerSecret, accessToken, accessTokenSecret);
Context context = new Context(authorizer, appToken, ServiceType.QBO, companyID);
DataService service = new DataService(context);
Customer customer=new Customer();
customer.setId("3");
Customer resultCustomer = service.findById(customer);
Last line gives current error (some strings replaced by stars):
com.intuit.ipp.exception.AuthenticationException: ERROR CODE:3200, ERROR MESSAGE:message=ApplicationAuthenticationFailed; errorCode=003200; statusCode=401, ERROR DETAIL:SignatureBaseString: GET&https%3A%2F%2Fsandbox-quickbooks.api.intuit.com%2Fv3%2Fcompany%***%2Fcustomer%2F3&minorversion%3D3%26oauth_consumer_key%***%26oauth_nonce%3D-4488452729022111661%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1450088662%26oauth_token%***%26oauth_version%3D1.0%26requestid%3Dc5bba96ea6894dc3be93588324778891
at com.intuit.ipp.interceptors.HandleResponseInterceptor.execute(HandleResponseInterceptor.java:91)
at com.intuit.ipp.interceptors.IntuitInterceptorProvider.executeResponseInterceptors(IntuitInterceptorProvider.java:94)
at com.intuit.ipp.interceptors.IntuitInterceptorProvider.executeInterceptors(IntuitInterceptorProvider.java:67)
at com.intuit.ipp.services.DataService.executeInterceptors(DataService.java:126)
at com.intuit.ipp.services.DataService.findById(DataService.java:215)
at test_qb.Start_QB.main(Start_QB.java:76)
It says something about auth error, but tokens are ok. Please help me out. What am I doing wrong?
Fixed. NO SLASH MIGHT BE IN THE ENDING OF URL IN CONFIG!
also use logging tools provided by SDK & log4j
I'm trying to login web site using Java and I succeeded. Below is the code I used.
String query = "myquery";
URL url = new URL(loginUrl);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-length", String.valueOf(query.length()));
con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0;Windows98;DigExt)");
con.setDoOutput(true);
con.setDoInput(true);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(query);
output.close();
DataInputStream input = new DataInputStream( con.getInputStream() );
for( int c = input.read(); c != -1; c = input.read() ) {
System.out.print( (char)c );
// this page returns JavaScript code
}
After this, I want to access another web page in same domain, so I tried below code.
URL url = new URL(anotherUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
... similar to above code ...
But this page asks me to login again. I think connection has been disconnected in the process of changing URL. (Onlt login page uses HTTPS protocol and other pages use HTTP protocol)
How can I fix this?
Someone please help
Keep in mind that HTTP is completely stateless. The idea of "logging in" to a site translates to (usually) setting cookies from an HTTP perspective. Those cookies are simply HTTP headers and they are sent with each subsequent request by your browser. So for you to maintain the logged in state its up to you get the cookies from the response headers and send them along with future requests.
Here is how:
Retrieving cookies from a response:
Open a java.net.URLConnection to the server:
URL myUrl = new URL("http://www.hccp.org/cookieTest.jsp");
URLConnection urlConn = myUrl.openConnection();
urlConn.connect();
Loop through response headers looking for cookies:
Since a server may set multiple cookies in a single request, we will need to loop through the response headers, looking for all headers named "Set-Cookie".
String headerName=null;
for (int i=1; (headerName = uc.getHeaderFieldKey(i))!=null; i++) {
if (headerName.equals("Set-Cookie")) {
String cookie = urlConn.getHeaderField(i);
...
Extract cookie name and value from cookie string:
The string returned by the getHeaderField(int index) method is a series of name=value separated by semi-colons (;). The first name/value pairing is actual data string we are interested in (i.e. "sessionId=0949eeee22222rtg" or "userId=igbrown"), the subsequent name/value pairings are meta-information that we would use to manage the storage of the cookie (when it expires, etc.).
cookie = cookie.substring(0, cookie.indexOf(";"));
String cookieName = cookie.substring(0, cookie.indexOf("="));
String cookieValue = cookie.substring(cookie.indexOf("=") + 1, cookie.length());
This is basically it. We now have the cookie name (cookieName) and the cookie value (cookieValue).
Setting a cookie value in a request:
Values must be set prior to calling the connect method:
URL myUrl = new URL("http://www.hccp.org/cookieTest.jsp");
URLConnection urlConn = myUrl.openConnection();
Create a cookie string:
String myCookie = "userId=igbrown";
Add the cookie to a request:
Using the
setRequestProperty(String name, String value);
method, we will add a property named "Cookie", passing the cookie string created in the previous step as the property value.
urlConn.setRequestProperty("Cookie", myCookie);
Send the cookie to the server:
To send the cookie, simply call connect() on the URLConnection for which we have added the cookie property:
urlConn.connect()
I have some working java code which does the following:
URL myUrl = new URL("http://localhost:8080/webservice?user=" + username + "&password=" + password + "&request=x");
HttpURLConnection myConnection = (HttpURLConnection) myUrl.openConnection();
myConnection.setRequestMethod("POST");
// code continues to read the response stream
However, I noticed that my webserver access log contained the plaintext password for all of the users who connected. I would like to get this out of the access log, but the webserver admins claim that this needs to be changed in my code and not via webserver config.
I tried changing the code to the following:
URL myUrl = new URL("http://localhost:8080/webservice");
HttpURLConnection myConnection = (HttpURLConnection) myUrl.openConnection();
myConnection.setRequestMethod("POST");
// start of new code
myConnection.setDoOutput(true);
myConnection.addRequestProperty("username", username);
myConnection.addRequestProperty("password", password);
myConnection.addRequestProperty("request", "x");
// code continues to read the response stream
Now the access log does not contain the username/password/request method. However, the webservice now throws an exception indicating that it didn't receive any username/password.
What did I do wrong in my client code? I also tried using "setRequestProperty" instead of "addRequestProperty" and it had the same broken behavior.
I actually found the answer in another question on stackoverflow.
The correct code should be:
URL myUrl = new URL("http://localhost:8080/webservice");
HttpURLConnection myConnection = (HttpURLConnection) myUrl.openConnection();
myConnection.setRequestMethod("POST");
myConnection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(myConnection.getOutputStream ());
wr.writeBytes("username=" + username + "&password="+password + "&request=x");
// code continues to read the response stream