How to access header values of request in Java Restlet? - java

I am developing web services using Restlet Java.
For this I want to protect some webservices from unauthorized clients. So I have written Filter class. In that Filter class I want to get the headers of the Request. But I am getting the following error -
java.lang.ClassCastException: org.restlet.engine.http.HttpRequest cannot be cast to javax.servlet.http.HttpServletRequest
The coding is -
public class MyFilter extends Filter {
#Override
protected int beforeHandle(Request request, Response response) {
int result = STOP;
HttpServletRequest httpReq = (HttpServletRequest) request;
String user_token = httpReq.getHeader("auth");
if(user_token.equals("xyz")) {
result = CONTINUE;
}
return result;
}
}
Please suggest me a way to access the header values of Request in Java Restlet?

I solved my problem using
Form headers = (Form) request.getAttributes().get("org.restlet.http.headers");
String user_token = headers.getFirstValue("Location");
I found this http://blog.yudongli.com/2009/12/get-request-header-in-restlet_13.html link useful.

Please also notice that Restlet provides an API for RESTful application. This means that you can access standard headers using this API. In most cases, you donn't need to use the attribute named "org.restlet.http.headers".
For example, if you want to set a Location header in the response, you add this code:
getResponse().setLocationRef("http://...");
Otherwise, since you talk about security, Restlet provides a generic API to support such aspect (see classes ChallengeAuthenticator, Verifier, Enroler).
Hope it helps you.
Thierry

If you are using Restlet 2.1-RC3 this is the way to get it
Series<Header> headers = (Series<Header>) getRequestAttributes().get("org.restlet.http.headers");
String auth = headers.getFirstValue("auth");
This is exactly how it's worked for me. None of the answers above did it. I hope it helps.

How would you handle seeking to parse an ID in the GET header from a client request ?
Would you approach this in the same manner ?
Since the:
Form headers = (Form) getRequestAttributes().get("org.restlet.http.headers");
returns all the header information and
String hID = headers.getFirstValue("Location");
gets the location(s)
How would you handle parsing out the ID ?

Series headers = (Series) getRequestAttributes().get("org.restlet.http.headers");
String origin = headers.getFirstValue("Origin");`
This is just an example of getting the Origin header. If you want to get Location, just change to headers.getFirstValue("Location");
As in the new version of Restlet, getRequestAttributes().get() returns Series instead of Form.

Related

Sending a post request to REST API from controller in Playframework with Java

I'm new to playframework and to REST API.
I want to send a POST request to REST API in a controller.
What is the best way to do it? Does play have a support for it or do I have to use a plugin?
Basically I want it to look like this:
User submits a form.
I load a form data in a controller.
I send form data as a POST request
Get response, do something with it and display result
So far I'm stuck at point 3, I have no idea how to do this.
Code to visualize what I have in mind:
public static Result processForm() {
Form<FormData> myForm = Form.form(FormData.class).bindFromRequest();
String text = myForm.get().text;
//Send 'text' in a post request and get response
text = doSomethingWithResponse(response);
return ok(resultpage.render(text));
}
I don't think it matters but this is the API I want to use:
http://open.xerox.com/Services/fst-nlp-tools/Pages/API%20Docs
The following line of code sends a request and waits for a reponse:
WS.url(feedUrl).setHeader("Content-Type", "application/x-www-form-urlencoded").post("arg1=val1&arg2=val2").get().asJson();

google-http-java-client json update existing object

i'm trying to use google-http-java-client on android and parse JSON responses from my server.
do do that i'm using the following code (provided by the examples of the project)
private static final HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
HttpRequestFactory requestFactory = HTTP_TRANSPORT
.createRequestFactory(new HttpRequestInitializer() {
#Override
public void initialize(HttpRequest request) {
request.setParser(new JsonObjectParser(JSON_FACTORY));
}
});
HttpRequest request = requestFactory.buildGetRequest(new GenericUrl(url + paramsList));
HttpResponse response = request.execute();
and everything works fine for new objects with
result = response.parseAs(PxUser.class);
but i need to update an existing object with the data from the json string.
with jackson only i can use the following code but with the google client i cannot find any solution.
InputStream in = -get-http-reponse-
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.readerForUpdating(MySingleton.getInstance());
reader.readValue(InputStream in);
so i need a way to update an existing object just like with this jackson example but by using the client.
is there a way? do i have to use jackson-databind.jar? how can i accomplish this?
thanks in advance
PS: i can switch to gson if its needed, no problem
It depends on whatever endpoint is receiving the API call, and what it expects the request to look like.
The Google HTTP Java Client simply handles the processes like making the call, encoding and decoding an object, exponential backoff, etc for you. It's up to you to create the request that does what you want and how the server expects it to look.
Likely, the API you're making the request to expects an object update to be made with a PUT request. The updated object is likely going to be the content of the request, encoded in some specific format. Let's assume JSON, since you're parsing JSON responses. So for the purpose of example, let's say you're going to request an object, modify it, then send it back.
First, you get the resource and parse it into your object:
PxUser myUser = response.parseAs(PxUser.class);
Then you modify the object somehow
myUser.setName("Frodo Baggins");
Now you want to send it back to the server as a JSON object in a PUT request:
// httpbin.org is a wonderful URL to test API calls against as it returns whatever if received.
GenericUrl url = new GenericUrl("http://httpbin.org/put");
JsonHttpContent content = new JsonHttpContent(new JacksonFactory(), myUser);
HttpRequest request = requestFactory.buildPutRequest(url, content);
HttpResponse response = request.execute();
System.out.println(response.parseAsString());
The specifics of how you encode and update your content is totally up to you and the API's specification. This is especially easy if you're creating the server receiving the call too.
If you're working with a preexisting API, you may want to update the question with the
specific problem (API "x" requires a response that looks like Blah; how do I do that in the google-http-java-client).
If you're working with a Google API, you'll want to be using the google-api-java-client which does all of this work for you.

Put request using rest

I have recently begun studyin the restlet interface. I don t know how to translate this method put using the restlet interface.
curl -X PUT http://ip:port/testdb2
How can I translate this request?
So far , i have this code :
ClientResource resource = new ClientResource("http://"+this.ip+":5984/");
// Send the HTTP GET request
Representation r=resource.get();
if (resource.getStatus().isSuccess()) {
resource.getResponseEntity().write(System.out);
}
resource.put(null);
if (resource.getStatus().isSuccess()){
resource.getResponseEntity().write(System.out);
} else
System.out.println("Error put");
How do I specify the new url?
I need this request to create a couchDB database.
Rephrasing your question, I'll use "How do I issue a PUT request to this url ..."
Per http://www.restlet.org/documentation/2.0/firstResource#part07
Perhaps something like
ClientResource dbResource = new ClientResource(
"http://"+this.ip+":5984/testdb2");
Representation r = dbResource.put(null);

How to secure URL parameters in java

Sample URL http://dineshlingam.appspot.com/guestbook?name=xxx&skills=zzz
Sample Code
public class GuestbookServlet extends HttpServlet
{
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException
{
String userName = req.getParameter("name");
String userSkills = req.getParameter("skills");
if(userName != null && userSkills != null)
{
res.setContentType("text/plain");
res.getWriter().println("Name : " + userName + ", Skills : " + userSkills);
}
else
res.sendRedirect(req.getRequestURI());
}
}
I am manually enter this URL to web browser.
How to secure parameters value.
Give me any one suitable example. Because I don't know the java concept and google-app-engine concept.
Really I don't know the SSL. So please I need detailed explanation of SSL with Example.
I am using eclipse to develop my application. Please help me. Thanks.
Your code is a classic example of a page vunerable to a CSS (Cross-Site-Scripting) attack. Using HTTPS wont mitigate that. Instead you need to escape any input before adding it to the page.
For example by using StringEscapeUtils.escapeHtml() and StringEscapeUtils.escapeJavaScript() from the Apache Commons Lang library.
Using https does not secure url parameter by any mean. You have to put parameters either in header or body if you want to make it secure. However if you are making a call directly from browser for this you cant put it in header neither in body because it is a a GET request. +1 to nfechner for highlighting XSS issue in your code.
For your problem here are the possible workaround with https:
Instead of GEt call use a POST call by putting this search in separate form in your page and use HTTPS on top of that.
If you want to use GET request you have to put the parameters in Headers, make a search page, When user hits the search button, make ajax call to above resource by passing it into header using https call.

Removing oauth_token from request header in Scribe

We're trying to connect with another company's custom API which uses two-legged OAuth to authenticate a request and send us a response.
At the moment the code we have is sending a request but it's not being authenticated at the other end and so sending a UNAUTHORISED response.
The steps we have investigated so far:
Connected to the remote site using an OAuth implementation in python using the same credentials.
Asked the other company to compare our OAuth request with another that succeeds to see if there is a anything missing in ours.
After the second point above, the only difference between our request and another working request is that the oauth_token parameter is present in our request and not in others. Furthermore, he said they have an oauth_body_hash_value in most of their requests but that's not present in ours - although they do get working requests without it.
Is there a way to remove the oauth_token parameter in Scribe? Alternatively, is the oauth_body_hash_value always needed? Can a request work without?
I've included the code below, I am completely new to OAuth so please feel free to tell me if there's something else that's wrong.
Note that the TestAPI.class extends DefaultAPI10a and just returns "" for all three required methods.
public class TestImporter {
private static final String REQ_URL = "http://test.com/";
private static final String KEY = "KEY";
private static final String SECRET = "SECRET";
// test variables
private static final String VAR1 = "Test123";
public static void main(String[] args) {
OAuthService service = new ServiceBuilder()
.provider(TestAPI.class)
.apiKey(KEY)
.apiSecret(SECRET)
.build();
Token token = new Token("", "");
OAuthRequest request = new OAuthRequest(Verb.GET, REQ_URL + VAR1 + "/");
service.signRequest(token, request);
Response response = request.send();
System.out.println(response.getBody());
}
}
Regarding your own answer seems that what you want to do is put the signature in the querystring and not use the Authorization header.
This, though valid is not recommended. Anyway if you really need to do it, there's a way of creating the OAuthService to "sign" in the querystring:
ServiceBuilder()
.provider(TestAPI.class)
.apiKey(KEY)
.apiSecret(SECRET)
.signatureType(SignatureType.QueryString)
.build();
Assuming their implementation is not broken, it should not matter that you have 'extra' OAuth headers included. Having said that, the oauth_token header is not optional (I assume you are communicating using OAuth 1.0). This header should contain the access token for the User. In your example you show this token as being blank, which is quite odd!
Now assuming for some reason that it is valid to send blank 'usernames' to this third party system, you will want to make sure that your OAuth signature is matching on both sides (yours and the other companies). Use a protocol sniffer to capture the value of the oauth_signature header, then ask your third party to verify that they generate a signature which is the same. If not then you probably have a signature hashing problem.
It turns out that when we thought we were sending a fully formed HTTP GET request, we weren't.
The library was adding all of the information to the header (where we were getting our information from), but not adding any oauth information to the request Url. I can only assume it's to do with us using two-legged authorisation (hence the empty Token).
By copying the map of oAuthParameters into queryStringParameters, it then allowed the Url to be formed correctly.

Categories

Resources