Why am I getting a 400 response code? - java

I am trying to get some acquaintance in using facebook API using Java (restfb). I am trying out the following code.
public class FBJava {
private String API_Key = "xxxxxx";
private String API_Secret = "xxxxxxxx";
public String firstReq = "https://graph.facebook.com/oauth/authorize?client_id="+API_Key+"&" +
"redirect_uri=http://www.facebook.com/connect/login_success.html& scope=publish_stream,offline_access,create_event";
public String secondReq = "https://graph.facebook.com/oauth/access_token?client_id="+API_Key+"" +
"&redirect_uri=http://www.facebook.com/connect/login_success.html&client_secret="+API_Secret+"&code=";
public static void main(String[] args) throws IOException {
FBJava fb = new FBJava();
System.out.println(fb.firstReq);
URL request = new URL(fb.firstReq);
HttpURLConnection conn = (HttpURLConnection) request.openConnection();
conn.connect();
int code = conn.getResponseCode();
System.out.println(code);
}
}
When I run the firstReq string in the browser manually, it is redirecting me to the correct page. But when I check the response code I am getting a 400 which means that its a bad request. I want to know why does it respond differently when I try to run it through the program. I know I am doing something wrong, but want to know what is the mistake and why is it occurring? Any kind of insight in this matter would be appreciated.

There is an error in the firstReq url. It contains a whitespace character between "& scope". Try this (I just removed the whitespace):
public String firstReq = "https://graph.facebook.com/oauth/authorize?client_id="+API_Key+"&" +
"redirect_uri=http://www.facebook.com/connect/login_success.html&scope=publish_stream,offline_access,create_event";

Related

HTTP POST from Java with JSON issue

Could anyone advise on why this code would not work for a HTTP Post with JSON? No response is received.
I am using Java in Android Studio - using the emulator on my laptop and want to access localhost on my laptop (so using 10.0.2.2).
Then want to take the JSON response, set this as a string just to test I am getting a response.
String jsonResponse = "No response received";
try {
//where write JSON with account details etc
JSONObject json = new JSONObject();
json.put("accountID", "test");
URL url = new URL("http://10.0.2.2:8082/queryTransaction");
HttpURLConnection httpcon = (HttpURLConnection) url.openConnection();
httpcon.setDoOutput(true);
httpcon.setRequestMethod("POST");
httpcon.setRequestProperty("Accept", "application/json");
httpcon.setRequestProperty("Content-Type", "application/json");
httpcon.setRequestProperty("Accept", "application/json");
OutputStreamWriter output = new OutputStreamWriter(httpcon.getOutputStream());
output.write(json.toString());
httpcon.connect();
jsonResponse = httpcon.getResponseMessage();//json response from API
}catch(Exception e){
}
Edit: I get this error which I have now found...
Method threw 'java.lang.NullPointerException' exception. Cannot evaluate com.android.okhttp.HttpUrl$Builder.toString()
so there are a few caveats with this. I got this working after making a few changes.
Make sure to set the charset.
setRequestProperty("charset", "utf-8");
Dont wrap the OutputStream, put it in a try-with-resources, and write the json as a byte array as utf-8 since that what we're accepting.
try (OutputStream output = httpcon.getOutputStream()) {
output.write(json.toString().getBytes(StandardCharsets.UTF_8));
}
Make sure your Json object is correct. If you're going to use accountID make sure you're consuming it properly. Gson/Jackson for example won't be able to parse this as conventionally it would accept account_id or accountId. Use #JsonProperty if needed.
#JsonProperty("account_id")
private final String accountId;
Example Controller with Spring Boot
#RestController
public class TestPostController {
public static class Account {
#JsonProperty("account_id")
private final String accountId;
public Account(String accountId) {
this.accountId = accountId;
}
public Account() {
this(null);
}
public String getAccountId() {
return accountId;
}
}
#PostMapping(path = "/test-post", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
public ResponseEntity<Account> response(#RequestBody Account account) {
return ResponseEntity.ok(account);
}
}

Test Java RESTful calls to Web API .Net

I have a weird question. I am working on a Java project for work, where we need to make HTTP GET/POST calls to our WEB API. I wanted to make a WebAPI testing project in C#; run it locally (localhost on some random port) and make sure I am sending the right stuff. That way I could control what was sent back(success, errors, JSON, XML, and different variables like that).
Here is some key stuff I have so far:
Client-Java code:
public String sendAPIRequest( HttpRequestMethod method, String apiURI, String payload) throws IOException
{
// Method is GET, POST....
// apiURL specific API navigating to.
// pauload is the html body.
if(payload == null)
{
payload = "";
}
// Establish a connection.
String strURL = String.format("%s%s", this.BaseURL, apiURI);
URL url = new URL(strURL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestProperty("Accept-Charset", this.CHARSET);
conn.setRequestMethod(method.toString());
conn.setRequestProperty("Content-Type", "text/json;charset=" + this.CHARSET);
conn.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
conn.setRequestProperty("Accept","*/*");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
// write the payload out, if it exists.
//if(payload != null)
{
try(OutputStream output = conn.getOutputStream())
{
output.write(payload.getBytes(CHARSET));
}
}
// read the response.
StringBuilder response = new StringBuilder();
InputStream input = conn.getInputStream();
try(Scanner inputScanner = new Scanner(input))
{
while(inputScanner.hasNextLine())
{
response.append((inputScanner));
}
}
return response.toString();
}
public String CheckForApplicableLicenses(String dCode, String key)
{
String result;
try
{
String APICall = String.format("/license/find_matching?d_code=%s&key=%s", dCode, key);
String Response = API.sendAPIRequest(HttpRequestMethod.GET, APICall);
// TODO Parse the String Response JSON/XMl.
result = Response;
}
catch(Exception ex)
{
// TODO: incorporate some sort of logging and error handling.
result = ex.toString();
}
return result;
}
Server-C#.Net code (tested with fiddler, and in the browser):
[Route("api/[controller]")]
public class LicenseController : Controller
{
[HttpGet]
[Route("find_matching")]
public IEnumerable<string> find_matching(string d_code = "", string key = "")
{
return new string[] { d_code, key };
}
}
Results so far:
I've gotten 404 errors, and I have been able to connect. Most of the time the Java client blows up when I get to the creating the InputStream. I've never been able to trip the breakpoint in the C# server.
Questions:
1) Is what I am doing even feasible? I'm really just trying to test the Java Client, without calling the API, before I am ready. Maybe it has something to do with not running the service on the default HTTP port of 80?
2) Is there a better way of testing this? I don't want to make call to our actual service until we are done.
Thanks in advance for an assistance.

Having trouble implementing Stormpath form Login/Authentication alongside REST oAuth authentication in the same application

We're using stormpath with Java & also trying to combine form Login with REST API authentication on the same application.
I've setup stormpath servlet plugin as described here https://docs.stormpath.com/java/servlet-plugin/quickstart.html... This works very fine.
Now, on the same application, we have APIs where I've implemented oAuth authentication with stormpath see here http://docs.stormpath.com/guides/api-key-management/
The first request for an access-token works fine by sending Basic Base64(keyId:keySecret) in the request header and grant_type = client_credentials in the body. Access tokens are being returned nicely. However trying to authenticate subsequent requests with the header Bearer <the-obtained-access-token> does not even hit the application before
returning the following json error message...
{
"error": "invalid_client",
"error_description": "access_token is invalid."
}
This is confusing because I've set breakpoints all over the application and I'm pretty sure that the API request doesn't hit the anywhere within the application before stormpath kicks in and returns this error. And even if stormpath somehow intercepts the request before getting to the REST interface, this message doesn't make any sense to me because i'm certainly making the subsequent API calls with a valid access-token obtained from the first call to get access-token.
I have run out of ideas why this could be happening but i'm suspecting that it may have something to do with stormpath config especially with a combination
of form Login/Authentication for web views and oAuth Athentication for REST endpoints. With that said, here's what my stormpath.properties looks like. Hope this could help point at anything I may be doing wrong.
stormpath.application.href=https://api.stormpath.com/v1/applications/[app-id]
stormpath.web.filters.authr=com.app.security.AuthorizationFilter
stormpath.web.request.event.listener = com.app.security.AuthenticationListener
stormpath.web.uris./resources/**=anon
stormpath.web.uris./assets/**=anon
stormpath.web.uris./v1.0/**=anon
stormpath.web.uris./** = authc,authr
stormpath.web.uris./**/**=authc,authr
Help with this would be highly appreciated.
The problem might be related to an incorrect request.
Is it possible for you to try this code in your app?:
private boolean verify(String accessToken) throws OauthAuthenticationException {
HttpRequest request = createRequestForOauth2AuthenticatedOperation(accessToken);
AccessTokenResult result = Applications.oauthRequestAuthenticator(application)
.authenticate(request);
System.out.println(result.getAccount().getEmail() + " was successfully verified, you can allow your protect operation to continue");
return true;
}
private HttpRequest createRequestForOauth2AuthenticatedOperation(String token) {
try {
Map<String, String[]> headers = new LinkedHashMap<String, String[]>();
headers.put("Accept", new String[]{"application/json"});
headers.put("Authorization", new String[]{"Bearer " + token});
HttpRequest request = HttpRequests.method(HttpMethod.GET)
.headers(headers)
.build();
return request;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
I've prepared an example that demonstrates oauth token creation as well as authorized access to protected pages using access tokens.
It builds off of the servlet example in the Stormpath SDK. The repo can be found here: https://github.com/stormpath/stormpath-java-oauth-servlet-sample
It demonstrates running a servlet application and having an out-of-band program get and use oauth tokens to access protected resources.
The core of the oauth part is in TokenAuthTest.java:
public class TokenAuthTest {
public static void main(String[] args) throws Exception {
String command = System.getProperty("command");
if (command == null || !("getToken".equals(command) || "getPage".equals(command))) {
System.err.println("Must supply a command:");
System.err.println("\t-Dcommand=getToken OR");
System.err.println("\t-Dcommand=getPage OR");
System.exit(1);
}
if ("getToken".equals(command)) {
getToken();
} else {
getPage();
}
}
private static final String APP_URL = "http://localhost:8080";
private static final String OAUTH_URI = "/oauth/token";
private static final String PROTECTED_URI = "/dashboard";
private static void getToken() throws Exception {
String username = System.getProperty("username");
String password = System.getProperty("password");
if (username == null || password == null) {
System.err.println("Must supply -Dusername=<username> -Dpassword=<password> on the command line");
System.exit(1);
}
PostMethod method = new PostMethod(APP_URL + OAUTH_URI);
method.setRequestHeader("Origin", APP_URL);
method.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
method.addParameter("grant_type", "password");
method.addParameter("username", username);
method.addParameter("password", password);
HttpClient client = new HttpClient();
client.executeMethod(method);
BufferedReader br = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
String readLine;
while(((readLine = br.readLine()) != null)) {
System.out.println(readLine);
}
}
private static void getPage() throws Exception {
String token = System.getProperty("token");
if (token == null) {
System.err.println("Must supply -Dtoken=<access token> on the command line");
System.exit(1);
}
GetMethod method = new GetMethod(APP_URL + PROTECTED_URI);
HttpClient client = new HttpClient();
System.out.println("Attempting to retrieve " + PROTECTED_URI + " without token...");
int returnCode = client.executeMethod(method);
System.out.println("return code: " + returnCode);
System.out.println();
System.out.println("Attempting to retrieve " + PROTECTED_URI + " with token...");
method.addRequestHeader("Authorization", "Bearer " + token);
returnCode = client.executeMethod(method);
System.out.println("return code: " + returnCode);
}
}

The best way to intercept a WebView request in Android

I am using a WebView in my app in which I must intercept requests. I am currently using the follwing code to do it.
public WebResourceResponse shouldInterceptRequest (WebView view, String url) {
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestProperty("User-Agent", userAgent);
String mime;
if (url.lastIndexOf('.') > url.lastIndexOf('/')) {
String ext = url.substring(url.lastIndexOf('.') + 1);
mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
} else {
mime = "text/html";
}
return new WebResourceResponse(mime, "UTF-8", conn.getInputStream());
}
Above code works fine in most cases, but no all. For example when I try to login to Outlook, it just shows that my email or password is incorrect, I have also seen other cases in which requests get broken, but everything works fine if I remove shouldInterceptRequest.
Is there any better way that the one I am currently using to intercept requests?
There are two issues with you code
Incorrect extension detection
For example, when the code try to get resource extension for this URL:
https://login.live.com/login.srf?wa=wsignin1.0&rpsnv=12&ct=1442476202&rver=6.4.6456.0&wp=MBI_SSL_SHARED&wreply=https:%2F%2Fmail.live.com%2Fdefault.aspx%3Frru%3Dinbox&lc=1033&id=64855&mkt=en-us&cbcxt=mai
It will return aspx%3Frru%3Dinbox&lc=1033&id=64855&mkt=en-us&cbcxt=mai which is wrong. There is special method for getting extension from the URL: getFileExtensionFromUrl()
According to documentation method MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext) may return null. In this case your code set wrong mime type for the page.
Here is the method code that take into account both these issues
#Override
public WebResourceResponse shouldInterceptRequest(WebView view,
String url) {
String ext = MimeTypeMap.getFileExtensionFromUrl(url);
String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
if (mime == null) {
return super.shouldInterceptRequest(view, url);
} else {
HttpURLConnection conn = (HttpURLConnection) new URL(
url).openConnection();
conn.setRequestProperty("User-Agent", userAgent);
return new WebResourceResponse(mime, "UTF-8",
conn.getInputStream());
}
}

FileUtils.copyUrlToFile is not working

I have fairly basic question i'm trying to download a PDF from this URL using java:
http://kundservice.svd.se/ui/templates/HttpHandler/PDFTidningen/PDFTidningen.ashx?date=2014-07-27&file=SVD_D_BILAGA_2014-07-27.pdf&mac=92267fcd3c75feff13154ba66870a523&free=True
here is my code "very basic":
public class Main {
private static final String PATH = "C:\\project\\DownloadTest\\src\\main\\resources\\tmp\\";
private static final String FILENAME = "data.pdf";
private static final String SvDPDFURL = "http://kundservice.svd.se/ui/templates/HttpHandler/PDFTidningen/PDFTidningen.ashx?date=2014-07-27&file=SVD_D_BILAGA_2014-07-27.pdf&mac=92267fcd3c75feff13154ba66870a523&free=True";
public static void main(String[] args) throws Exception{
File file = new File(PATH + FILENAME);
URL url = new URL(SvDPDFURL);
FileUtils.copyURLToFile(url, file);
}
}
the problem is that file is empty, what i'm i doing wrong.
Just make it https instead of http.
https://kundservice.svd.se/ui/templates/HttpHandler/PDFTidningen/PDFTidningen.ashx?date=2014-07-27&file=SVD_D_BILAGA_2014-07-27.pdf&mac=92267fcd3c75feff13154ba66870a523&free=True
It is happening because there is a redirect when you hit the url. It redirects to https. Browsers get the response and the response code is 302 then redirects to the given url but the FileUtility can not handle that.
To confirm use firebug or chrome developers tool by hitting F12 and go to Network tab.

Categories

Resources