I use SoapUI to test a certain webservice. The wsdl the webservice returns is not optimal for SoapUI, so I want to modify the response. Since the wsdl is still subject to change, i want the connection to go through a custom proxys, which modifies the response if the response is from certain pages. Other pages should be put through untouched.
How would I create such proxy in Java? I want to do as few HTTP specific logic in the proxy, just alter the response of some pages.
Related
GET http://localhost/foo/api/v1/bars/:id
How to have different JSON responses registered for a GET call. We would like the GET call to return a separate response based on whether a CLI is invoking or the user interface is calling the API by passing a query parameter. But how do we register different serializers dynamically on the response.
You can use a User-Agent request header to identify the application doing the request. There are good tutorials to check how to access the headers in Spring, like this Baeldung one.
I'm facing a particular use case while using Wiremock standalone API.
I would like to be able to reuse a response body generated by stubbing for a another request (stubbed as well) as a context model. The purpose is to store for a generated Id the entire response data, that would allow me to serve it again simply knowing the Id, in a get method particularly (where there is no request body).
Is there a way while defining a stub of response to capture the generated response, in order to store it?
Or if you have other better idea.
Finally I solved the problem by using an okhttp interceptor (which depends on your client solution).
In the interceptor, I store every response data (e.g.: a generated ID) and set them in every next request headers when it matches with part of the the response stored.
adding them to the request headers allows me to access them in a json template file for instance
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.
Is there any known way to send a new SOAP request from one servlet to another within a single WebContainer without consuming an additional web container thread?
So far I have tried using RequestDispatcher.include(request, response) with a customised request and response so I can provide my own input and intercept the callee's output.
With this, I am able to intercept the output without issue (using a custom HttpServletResponse class that writes to a buffer), but I have been unable to send customised input with this method. I am using an extension of HttpServletRequestWrapper to provide my own input to the third party application (instead of the original request to my application), however it seems like either WebSphere or Axis are discarding my wrapper and I therefore get a SOAP fault instead of a valid response.
For clarity, I don't need to forward the original request to the callee (which is a JSONP GET request), I need to fabricate a new SOAP request within my application and send that to the callee instead.
Is there a variation of this method I should try? Is there a completely different way to send a request within a single web container?
Many thanks to those who respond.
For context, I am writing a JSON/REST web service to be run on WebSphere Application Server, which in turn calls a third party product via SOAP on Axis 2. Unfortunately this third party product is only available via a SOAP HTTP interface, despite itself being a Java servlet running inside the same WebSphere web container.
Previously I have been calling this application using an HTTP proxy generated with the SOAP proxy generator based on third party product's WSDL. This works fine however it means that one call to my service in turn consumes two web container threads which is a severe vulnerability. Once the web container thread pool is full, it stays full since the requests to my servlet are holding threads until the third party application responds, which it is not able to do because no threads are available to process the HTTP request my servlet made.
Update:
I have done some further testing and been able to do this type of forwarding to my REST service successfully. I am able to query my REST/JSON service with a synthetic ServletRequest and ServletResponse, therefore allowing me to achieve my original purpose if the product I was calling did not use an Axis SOAP interface.
It appears that Axis is looking in a different place for the SOAPAction header than I expected, as I always get a "no SOAPAction header found!" fault message back despite me adding a SOAPACtion header to my synthetic request (I have verified that the SOAPAction header is in fact added).
It turns out that the reason I could not get the service to work with Axis due a "missing" SOAPAction header has nothing to do with WebSphere or Axis at all. It was a ConcurrentHasMap that somehow was comparing two equivalent strings and saying they were different, so the SOAPAction header was never returned when Axis looked for it. To work around this, I simply tested for queries on 'SOAPAction' and hardcoded the response.
So, for future reference here is the general setup I used.
Create a class implementing HttpServletRequest that wraps another HttpServletRequest to be provided in the constructor. In this class the getHeader method was overridden to catch requests for the SOAPAction header, other header requests may be forwarded to the original request (Axis doesn't seem to look for anything other than the SOAPAction header). I also over-rode the getInputStream method to return my own ServletInputStream implementation that simply reads from a byte buffer using a fixed text encoding, and the getContentLength method to return a length consistent with my data.
Create a class implementing HttpServletResponse, which only correctly implements the getWriter and getOutputStream methods. The getOutputStream method return a custom ServletOutputStream implementation that records its output to a byte buffer. The getWriter method returned a special PrintWriter that wrote to the same ServletOutputStream returned by getOutputStream, except this writer always needed to flush after writing - I am not sure why this had to be case.
Before dispatching the request using RequestDispatcher.include(request, response), I wrapped my synthetic HttpServletRequest in a HttpServletRequestWrapper, which oddly seemed to help. I then used RequestDispatcher.include(request, response) in the usual fashion, and read the SOAP service's output from my custom ServletOutputStream's byte buffer to process as it in the same as if I had issued an HTTP request.
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.