I have a jersey server up and running. When running from browser directly I get the correct response. However when I try to access the rest service from angular.js's $resource I get the following error in the console when trying to access to the correct url. I've tried to read all materials online, like http://simplapi.wordpress.com/2013/04/10/jersey-jax-rs-implements-a-cross-domain-filter/ to setup a CORS filter, but the guide seems to be dated and cryptic. (im using the newest implementation of jersey).
Failed to load resource: Origin localhost:63342 is not allowed
by Access-Control-Allow-Origin.
method that makes the data I need available in jersey.
#Path("/id/{id}")
#GET
#Produces(MediaType.APPLICATION_JSON)
public boolean validateSSN(#PathParam("id") String id) {
IdValidator idv = new IdValidator(id);
return idv.Validate();
}
accessor method in angular.js:
services.factory('ReplyFactory', function ($resource) {
console.log("test");
return $resource(baseUrl + '/myproject/api/validate/id/:id', {id: '#id'},
{'get': { method: 'GET' }});
});
Well what you need to do is to ensure that all responses from your resources have following http headers:
Access-Control-Allow-Origin - specifies from which origins requests should be accepted (localhost:63342 in your case)
Access-Control-Allow-Headers - specifies which headers are allowed to be used via CORS
Access-Control-Allow-Methods - specifies which methods are allowed to be used via CORS
And there are other headers like Access-Control-Allow-Credentials and etc.
So you just need to add at least Access-Control-Allow-Origin header to your responses. How you can do it depends on your environment.
You can manually define those headers on each resource .
You can define Jersey filter to add CORS headers to all responses
You can use servlet filter to add CORS headers to all responses
There are also specific solutions for Tomcat and Jetty
There many ways how to do it but all of it is about the same thing - you just add an extra header to your server responses.
Related
I have a Rest API, created with Camel Rest-DSL. There is a rest, that consumes GET with a list of params, some of which are mandatory.
Route config:
rest().get("/{{camel.rest.version}}/myget")
.param()
.name("accountNumber")
.dataType("string")
.type(RestParamType.query)
.required(true)
.endParam()
.param()
.name("someId")
.dataType("string")
.type(RestParamType.query)
.required(false)
.endParam()
.produces(REST_PR_CN_TYPE)
.responseMessage().code("200").message("OK").endResponseMessage()
.responseMessage().code("500").endResponseMessage()
.route().routeId("rst_cardsInfo")
.log(LoggingLevel.INFO, "ApiRq Recieved http request")
.log(LoggingLevel.DEBUG, "AccountNumber: ${header.accountNumber}, SomeId: ${header.someId}")
.id("rst_rst_info_recieved")
.to("direct:drt_rst_info")
.endRest();
When I open swagger-ui generated page, my API is looks fine. Param accountNumber is marked as required, someId - as not required.
Using any other tool I can send a request without any params and receive HTTP.200 as a response. I expected, that if a param is required, but not present in request, the request would fail. Spring Rest for example makes sure that all mandatory params are present.
Is there any mandatory params presence validation in Camel? May be I misconfigured something?
Ah okay. There is no / only a little bit of validation today in the rest-dsl. It relies on the chosen HTTP component (servlet, restlet, undertow etc.) to do that.
But frankly we can improve thise and let camel-core do some pre-validation if the options has been specified as in your example.
I have logged a ticket: https://issues.apache.org/jira/browse/CAMEL-12533
Thank you, #Claus Ibsen.
From Camel 2.22 version onwards, now we can validate incoming client request.
The validation is turned off by default. In order to configure it, we need to use clientRequestValidation as follow :
restConfiguration()
.component("restlet").host("localhost").port("port")
.clientRequestValidation(true);
For more details visit : Client Request Validation - Apache Camel Manual
I would like to provide the actual get request in a response. I am free to choose between placing that information into the header or the body of the response.
The current project setup includes:
Nginx as reverse proxy
Spring boot application
which are potential candidates to put in that logic.
Request:
GET http://localhost/api/users/2/photos/2
Response:
BODY {"some": "values",
"_request": "GET http://localhost/api/users/2/photos/2"}
or
HEADERS "custom-header-get-request": "GET http://localhost/api/users/2/photos/2"
BODY {"some": "values"}
I can easily add the information to the response of each Responseobject within the Controllers of the spring boot application. This approach is quite cumbersome, as it leads to a lot of codechanges and allways needs to be in mind that each Controller should take care of providing the requestinformation to the response, achieving the first solution.
Which other options do i have?
Is there a way to get access to the request parameters in a custom com.google.api.server.spi.config.Autenticator?
I would like to authenticate my users using a token, sent as a request parameter according to https://<mydomain>/_ah/api/v1/myapi/endpoint?token=<mytoken>. Unfortunately, in this case, it is not possible to send it as a request header. Currently, I manage authentication in each endpoint (where I do have access to the request parameters, either through the HttpServletRequest object or through a named parameter) but it would be nice to decouple auth from implementation.
As I understand, Cloud Endpoints will wrap the original request in a new POST request to /_ah/spi/... but only the request headers will be accessible in the Authenticator.
It doesn't matter if the initial request to Cloud Endpoints is GET or POST.
Your understanding is correct--your request is translated such that all query parameters are injected as part of the JSON body as well. I believe the body does have the query parameter, but I'm not 100% sure on that. If you upgrade to the new Endpoints Frameworks beta, you can access it using getParameter or getParameterValues on the servlet request, as you would expect.
I have a java web application which publish a service that returns an object in JSON format, and I have another java web app just to consume that service through a JSONP call and show the response. In my local machine it's working fine, but now that I want to test it in a web environment (Layershift in my case), I can't get the JSON object. I don't see any errors on Chrome developer tools, but when I look into the Response tab (in Network option) I see the source code of the login page of my application. Let me show you the my code
Controller with the service:
#RestController
public class MyController {
#RequestMapping(value="/myservice/get/{somevar}")
public MappingJacksonValue getMyObject (#RequestParam String callback, #PathVariable String somevar, HttpServletRequest request, HttpServletResponse response) {
MyObject obj = new MyObject();
//some logic
MappingJacksonValue value = new MappingJacksonValue(obj);
value.setJsonpFunction(callback);
return value;
}
}
javascript code for call the service:
$.fn.callWithJsonP = function(somevar) {
var url = "/myservice/get/" + somevar + "?callback=myCallback";
$.getJSON(url, function(data) {
if (data.value.status == "OK") {
//shows the data contained
}
});
}
Apache configuration (added to avoid CORS error), present in both applications
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Header always unset X-Frame-Options
This is working perfectly on muy local machine (except for the Apache, I don't use it locally), but as I said, on a web environment I receive the source code of my login page. In the Headers tab I can see the headers added in Apache, and the status code of the response is OK, any clues about what's goin on?
Kind regards
UPDATEI've removed the Apache web server, and even tested the web service with Postman (meaning, no second application), and still the same result. I've tried changing #RestController for #Controller and returning an instance of MyObject (instead of MappingJacksonValue), with no results, please help me
I am probably way off here, but is it possible that you have a servlet filter or other part of your web app config that is routing your get request to your login page before your REST framework is able to map it to your endpoint? I use Jersey for this usually, so I am unfamiliar with Spring's RestController, but I assume it is doing similar thing - routes URLs that match to the java code. If you are seeing login page in response it sounds like something is interfering and trying to force user to login before Spring directs to your endpoint method.
It seems like you have a fallback set in your server, maybe configured for a single page application. This is normally used for routing with HTML5 mode using routers like angular's.
you are getting the login page code as response because the login is failed and you are redirected to the same page.. so before calling the service first you need to do the authentication and then by using the authentication token call the service..
I am presuming that GWT RPC actually uses RequestBuilder.
Is there a way to extract the RequestBuilder instance used by my RPC service async requestor?
Actually, my question is, how do you extract the RequestBuilder instance to insert the authentication token as a http header? Is there a way to insert http headers into an RPC service request?
Even if I could insert a http header into the request, how then would the remote servlet be told to expect that auth token? Therefore, in fact, does GWT RPC provide a framework for secure authentication at all?
I am thinking the answer is NO, or at least not in a convenient way. Am I right?
I am coming from having used RestEasy in combination with RestyGWT over SSL, where we can insert headers anytime we wish. BTW, RestyGWT constructs its request to use RequestBuilder.
My actual motivation is comparing the security effectiveness between GWT RPC and GWT JAX-RS (RestyGWT + RestEasy). So if you, as the answerer, have an alternative detailed discourse comparing the security effectiveness of RPC with direct use of RequestBuilder or REST (rather than answering this question directly) please feel free to elaborate.
Am I right to presume that GWT RPC is not security friendly/effective and I should avoid using GWT RPC for secure authenticated requests?
You can have your async method return a Request or a RequestBuilder instead of void. Request allows you to abort() a pending request, whereas RequestBuilder allows you to modify the request before its sent (if you declare the return-type as RequestBuilder, you're responsible for calling send() to actually make the request).
Alternately, you can use an RpcRequestBuilder to customize the RequestBuilder for each and every call made with a specific async service proxy.
As far as I know there is no built in security solution for gwt rpc.
But If I need such authentication I would make the following steps:
1) To be able to set http headers you can make your custom request builder, as I do myself:
MyServiceAsync myService = GWT.create(MyService.class);
MyRequestBuilder myRequestBuilder = new MyRequestBuilder();
myRequestBuilder.addHeader("header", "value");
((ServiceDefTarget) serviceInstance).setRpcRequestBuilder(myRequestBuilder);
MyRequestBuilder extends RpcRequestBuilder. And inside MyRequestBuilder I override method doFinish(RequestBuilder rb) where I put my headers.
Maybe it is not a super solution, but I haven't yet found anything better.
2) For the server side I would implement the AuthenticationFilter for checking the headers and perform server side auth functions prior calling the Servlet.