jetty AsyncProxyServlet/AsyncMiddleManServlet - java

I am planning to use one of the above servlets. My use case is, client hits one of the server [This is where I would be using Proxy or MiddleMan servlet]. From here I would like to talk to other services based on the request URL. Can I use these servlets for this use case
example:
client -->http://<headend>/service1/x/y ---In MiddleManServlet -- http://server1/service1/x/y
client -->http://<headend>/service2/x/y ---In MiddleManServlet -- http://server2/service2/x/y
Can this be accomplished using this servlets?. I know I have to override rewriteTarget method.

Yes, this can be accomplished using something like Jetty's AsyncProxyServlet. You would basically need to set up your app container to pass requests with a certain path to your servlet ("service1" for example) and then in your servlet you would validate if the path the user was trying to hit was valid or whether it is an error (i.e. you probably don't want people proxying through your app to random services).
http://download.eclipse.org/jetty/9.3.11.v20160721/apidocs/org/eclipse/jetty/proxy/ProxyServlet.Transparent.html

Related

Apache Wicket - Custom servlet

I am trying to integrate Wicket (1.5.16) with the "Single Sign-On". In this process, IdP posts a bunch of attributes back to the Wicket application using HTTP POST.
If I use , it looks for life cycle and also adds some numbers to the form, etc. I am looking for the following solution,
1) Create a Servlet/Some Wicket class which can receive the POST requests.
2) If SAML authentication is successful, forward to a private Internal .
Please let me know if you have any submissions.
You can wrap Wicket in another Servlet Filter. This way your Filter will receive the request first and may decide whether to process it or pass it to Wicket.
To accomplish this you just need to define your <filter> above/before Wicket's filter/servlet in web.xml.

Rest api - update single field of resource

Lets say I have rest endpoint for my Driver resource.
I have PUT method like this
myapi/drivers/{id}
{body of put method}
I need to add functionality which will allow to 'enable' and 'disable' driver
Is it good idea to create new endpoint for that like this?
PUT myapi/drivers/{id}/enable/false
or it is better to use existing endpoint ? One problem with using existing endpoint is that driver has lot's of fields(almost 30) and sending all those fields just for updating only 'enabled' or 'disable' driver is something overkill.
What do you think?
This is exactly what the HTTP method PATCH is made for. It is used in cases where the resource has many fields but you only want to update a few.
Just like with PUT, you send a request to myapi/drivers/{id}. However, unlike with PUT, you only send the fields you want to change in the request body.
Creating endpoints like myapi/drivers/{id}/enable is not very RESTful, as "enable" can't really be called a resource on its own.
For an example implementation of a Spring PATCH endpoint, please see this link.
Use PATCH Http metod to update one field
PATCH myapi/drivers/{id}/enable

Interservlet communication

I have a Websocket servlet and a Rest servlet.
I want to inform the websocket servlet about changes in order to write these "events" via websocket to a server.
I could only find the forward() and include() approach. But they seem to me that they only can forward onGet, onPost, etc.
do I miss something?
Indeed, forward() and include() are meant to be used when processing a request. So they might not be the best option given what you want to achieve.
What you could do is create a third component, let's call it EventManager for the time being, and have the Rest servlet signal changes to the EventManager. The websocket, on the other hand, could be notified by the EventManager that new data are available and then get that new data in order to write it back to the client.
In this approach it is essential that both the Rest servlet and the websocket servlet share the same instance of the EventManager. You could achieve that by marking the EventManager as a singleton EJB by adding the #Singleton annotation, and inject it to both the Rest servlet and the websocket servlet.

Guice servlet DSL, filter all but one URL

I want to filter all requests to my web application through my "SecurityFilter" which checks that a session variable "authToken" is valid. The problem is that in order to get this token you need to hit the "AuthServlet" which is at /auth.
I need to filter all servlets except the /auth servlet with my "SecurityFilter". How can I do this via guice-servlet?
I thought of trying to no avail...
filterRegex("!((.)*auth(.)*)").through(PortSecurityFilter.class);
^((?!/authorize).)*$ worked.

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