Default Jersey query parameter - java

I have Jersey client with a lot of functionality and now requirements are changed and I need to implement multitenancy for it.
I tried to implement automatic tenancy resolving on server side using URL of client that sent the request, but method getRemoteHost() from ServletRequest class in some cases returns only IP, but not a domain name, so it seems that I need to implement multitenancy feature also on client side and pass some parameters in query.
Is it possible to set default query parameter for the whole Jersey client instance without adding it into every method?

Yes - add a client filter that adds the parameter to every outgoing request - see http://jersey.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/client/filter/ClientFilter.html

Related

How to have different JSON responses registered for a GET call

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.

How should my proxy intercept packets

I have two web servers A and C. Because of rules, policies etc A cannot communicate directly with C' (Crequires requests to have special security headers andA` does not support this)
I want to create a "proxy" called B in Java, to facilitate communication between A and B but I having trouble with it conceptually.
When you create a proxy, don't you have to change the hard coded URLs on all your services to now travel through the proxy? And then I suppose you must pass your destination as a query parameter somehow, for example
http://proxy.com/?destination=mydestination.com
Is this how a proxy would work?
(I have found a few similar questions but they do not resolve the fundamental question I am having i.e. How packets reaches Destination throgh proxy servers?)
Don't write your own proxy from scratch that will be a redo, there are a plenty of proxy implementations out there
Spring framework
Spring Boot implementation for (Netflex/Zuul) https://github.com/Netflix/zuul / https://spring.io/guides/gs/routing-and-filtering/
Standard Servlet
https://github.com/mitre/HTTP-Proxy-Servlet
in case if you are intrested in how you can build up your own proxy , here is a simple example using spring framework (Servlet implementation is not that far from spring implementation)
#RestController
public class ProxyController {
/**
* request handler for all the requests on the registered context intended to be proxied
*
* #param request
* #return
*/
#RequestMapping("/**")
public String defaultGateway(HttpServletRequest request) {
// edit the original request headers,body etc
String originalPath = request.getRequestURI();
// then fire another HTTP request using the same URI
return "ProxiedResult"; // return back the result you get from
}
}
the example above is a start point on how to implements HTTP proxy or how it is working there are many things to cover which is droped off like security for instance

GWT RPC security, http header, authentication and requestbuilder

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.

Apache CXF: Forwarding an information from an interceptor to the actual webservice implementation

I'm running a JAX-WS web service which is based on Apache CXF 2.3.1 on a JBoss6 server.
My service offers a function getWeight. This function should return the values in different units (kilos, pounds) depending on an additional information within the SOAP header. For that purpose I have added my own interceptor:
public class MySoapHeaderInterceptor extends AbstractSoapInterceptor
{
public MySoapHeaderInterceptor()
{
super(Phase.USER_PROTOCOL);
}
...
}
The intercepting works fine and I can parse the additional element from the SOAP header and can set up a variable based on this element:
boolean poundsRequested = true;
Now my problem occurs. I don't know how to forward the variable poundsRequested to my actual WebService implementation MyServiceImpl. This class is calling another class ValueReader where I finally need the information from the SOAP header.
I've already tried to set up a global static variable ValueReader.poundsRequested. But such a solution is not thread safe. It might happen that the calls of two clients interfere, and can overwrite each others set up variable.
To sum up: I basically need a possibility to forward a variable from an Apache CXF Interceptor to the actual webservice implementation. Moreover the value of this variable needs to be unique for each request.
In the interceptor, you can save the values that you need on the incoming message:
message.put("my.value", value);
Inside your implementation, you can do one of two things:
1) Have the standard JAXWS WebServiceContext injected via an #Resource thing and call
context.getMessageContext().get("my.value");
2) Since you are tied to CXF anyway, do:
PhaseInterceptorChain.getCurrentMessage().get("my.value");
Ideally, the format in which the weights are requested should be a part of your payload - it does not make sense for it to be a header.
You may not need an interceptor for getting hold of this header, if you are using JAX-WS(recommended with CXF), you can get to this using #WebParam annotation with header attribute set to true.

How to send a username between web service requests?

Basically the problem is this:
There is a stored database procedure that takes a username as an argument and produces some XML data depending on it. It is called by a method with no arguments in an unsecured web service (let's call that web service WSA). There is also another web service (let's call it WSB) which is supposed to call WSA. In this setup, WSA should only ever be called by WSB and never by anyone else. WSB is what users call and it is the way they get the required XML data. The web services are deployed on OC4J, and they have security enabled on them. WSB is secured by OC4J and is accessed by providing the username and password of an OC4J user.
When testing a web service, OC4J provides you with a form where you can enter login information prior to invoking a web service. If you select to include security info in the header and preview the message before invoking the service, the username and password are in the message.
My problem is that I can't get the security information (or at least the username) to reach the endpoint implementation and invocation of the stored procedure.
So far I have created WSA, made a web service proxy that refers to it, and created WSB based on the proxy.
What I have tried so far to get the username (and why it doesn't work):
Had WSA implement javax.xml.rpc.server.ServiceLifecycle. This provides WSA with an instance of javax.xml.rpc.server.ServletEndpointContext, which provides me with a java.security.Principal. However, that Principal is null if I call WSB (which in turn calls WSA). If I secure WSA and call it directly, the Pricipal is not null and contains the user (but it doesn't solve the problem, because I need to call WSB, not WSA).
Created handlers (extending javax.xml.rpc.handler.GenericHandler) for both services, which were supposed to be able to process the message. One thing really baffled me here. The handler methods get called correctly - the WSB handler handles the request, then the WSA handler handles the request, then the WSA handler handles the response and finally the WSB handler handles the response. But when I tried printing the messages to a file on each step, I found out that even at the first step (when WSB handles the request) there is no security information in the message. No username, no nothing. The message is in fact quite different from what is shown on the invocation page when previewing the request message before invoking the service.
Tried injecting an instance of WebServiceContext by using the #Resource annotation, but apparently OC4J doesn't support this.
If anyone can shed some light on where I might be doing something wrong, I would be very thankful.
The problem is that "WSA is called by a method with no arguments in an unsecured web service". So, there is no security context for WSA to pick-up the user id from...
The simplest fix might be to change the WSA API to accept a user id in the request parameters.
HTH
Tom

Categories