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.
Related
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.
Actually, my requirement is, client can call my rest based services in both synchronous (request-response) or in asynchronous (request-acknowledgment-response) mode. Now, based on the request type, I have to follow the mode.
Now, my question is, is there any way, from the request itself, by default, is there any indicator, which will tells the clients desire request-response model.
Service protocol is http.
if not possible, then what will be the best practice, to handle this type of scenario.
You can have the client specify its preference to receive an asynchronous response via a header:
Prefer: respond-async
You can find details here: https://www.rfc-editor.org/rfc/rfc7240#section-4.1.
I am not aware of any way to explicitly request the opposite, a synchronous response.
To differentiate between two request you can pass the attributes in the header along with the request.
If it is Sync Request
Set Header : RequestType : Sync
If it is Async Request
Set Header : RequestType : ASync
This is the easiest way you can use.
So I have a org.springframework.stereotype.Controller and what I want to do is process the request normally if HTTP headers HA and HB are specified. But if the request has query parameters QA and QB specified, I want to redirect the request WITHOUT QA or QB, but WITH HTTP headers HA and HB such that HA has the value of QA and HB has the value of QB.
For example, if the incoming request is HTTP GET ~/rest/mortgage with HTTP headers x-name=foo and x-date=bar, I would process that request as is. But if the incoming request is HTTP GET ~/rest/mortgage?x-name=foo&x-date=bar, I want to redirect to myself with the request HTTP GET ~/rest/mortgage with HTTP headers x-name=foo and x-date=bar.
By doing this, I can have a single code path dealing with both styles of making the HTTP request just by adding a simple check at the controller level. This is because I pass the HttpServletRequest around to various parts of the code, so if I have the consistency of always having HA and HB instead of QA and QB, it reduces the cyclomatic complexity of the code.
Is this possible? And if so, how?
If this is not possible, I can achieve my desired result by defining my own wrapper for HttpServletRequest that does the transformation for me, but that's not as elegant of a solution.
If you want to intercept the HTTP request you need to use a Servlet Filter.
In order to replace the URL you have to get the Dispatcher for the new URL, and then dispatch the request again with the forward() method.
Something like this:
servletRequest.getRequestDispatcher(modifiedURL)
.forward(servletRequest, servletResponse);
However, you are not explicitly allowed to modify the HTTP headers. The way around this is to wrap the request and have a proxy object that handles this, by extending HttpServletRequestWrapper. It already implements the HttpServletRequest so you shouldn't have any issues using it wherever you are interacting with the original servlet request.
You can simply extend it and add your own method like addHeader() and keep an internal Map or something of the extra artificial headers you are adding. Then you have to just override getHeaderNames() and getHeader() to also combine the original headers with your own extra ones.
The last thing you will need to do is wrap your original servletRequest in your new wrappedServletRequest in your Filter. So something like this (where WrappedServletRequest is your new implementation that extends HttpServletRequestWrapper):
WrappedServletRequest wrappedServletRequest =
new WrappedServletRequest(servletRequest);
wrappedServletRequest.addHeader("yourHeader", "yourValue");
wrappedServletRequest.getRequestDispatcher(modifiedURL)
.forward(wrappedServletRequest, servletResponse);
Remember to add your <filter> and <filter-mapping> of your Filter in your web.xml for it to work.
You might want to have a look at this article for more details. It has some more information as to why you have to do it this way.
I didn't try it myself, so comment below and confirm if you manage to get it to work.
I'm trying to build a login screen for my GWT app. When you click the login button, the credentials (username & password) need to be sent to the server for authentication. I'm wondering what server communication method is a best fit for this: GWT-RPC or RequestFactory.
My understanding is the RequestFactory is more efficient and recommended over GWT-RPC, but it's more of a data/entity/persistence framework than a request-response framework like RPC. So although many GWT afficionados recommend using RequestFactory over GWT-RPC, I don't think RequestFactory can be used for this scenario. After all, I don't want to CRUD a login request, I want to send credentials to a server, perform secured authentication, and return a response to the client.
Am I correct? Is GWT-RPC my only option? or
Can RequestFactory be used. If so, how (need to see a code example of both client and server code)?
You can use either, although RF is very used with EntityProxy, it also is thought to work with ValueProxy which mean transmit any type. RF facilitates as well execution of remote procedures passing Proxy types or primitive types.
Said that, I would use the technology used primarily in my app. If you are using RPC send your login/password in a RPC request, but if you are using RF use it, so as you dont mix things, although you can mix RF, RPC, and plain Ajax without problems.
What you have to be aware of, is that normally, in applications requiring authentication you have to use a filter to check whether the user has a valid session when requesting RPC or RF, so in the case of sending a request for login, you have to jump somehow the auth filter.
Related with security, both scenarios are the same, you have to do the request in an https enabled environment.
[EDIT]
This could be the interface for the client and the remote implementation of a RF call for login, as you can see it is really easy, you can add any method you need to these classes:
#Service(value = LoginUserService.class)
public interface LoginUserRequest extends RequestContext {
Request<Boolean> login(String username, String password);
}
public class LoginUserService {
// Using static you dont need to provide a Locator for the service
static Boolean login(String username, String password) {
return true;
}
}
Related with auth filters for RF, you can take a look to this: GWT RequestFactory authentication functions
With both technology you can send such information to server side, but as already you pointed out the RequestFactory is dedicated to entity management. In your case is better to use GWT-RPC because in order to only send the credentials server side, and eventually retrieve the authentication result, you don't need the RequestFactory surplus (delta transmission, entity management).
For authentication, I would (almost) always use RequestBuilder, i.e. a simple HTTP(S!) POST. Why? Because this way you can implement a general authentication mechanism, that can not only be used by GWT apps. You gain the flexibility to add a simple HTML login page, single sign-on, standard server-side mechanisms (e.g. Spring security), etc.
A simple GWT re-login dialog is also no problem with RequestBuilder - to submit just username/password, GWT-RPC or RF is simply not necessary.
I'm writing a simple Google Web Toolkit service which acts as a proxy, which will basically exist to allow the client to make a POST to a different server. The client essentially uses this service to request an HTTP call. The service has only one asynchronous method call, called ajax(), which should just forward the server response. My code for implementing the call looks like this:
class ProxyServiceImpl extends RemoteServiceServlet implements ProxyService {
#Override
public Response ajax(String data) {
RequestBuilder rb = /*make a request builder*/
RequestCallback rc = new RequestCallback() {
#Override
public void onResponseReceived(Response response) {
/* Forward this response back to the client as the return value of
the ajax method... somehow... */
}
};
rb.sendRequest(data, requestCallback);
return /* The response above... except I can't */;
}
}
You can see the basic form of my problem, of course. The ajax() method is used asynchronously, but GWT decides to be smart and hide that from the dumb old developer, so they can just write normal Java code without callbacks. GWT services basically just do magic instead of accepting a callback parameter.
The trouble arises, then, because GWT is hiding the callback object from me. I'm trying to make my own asynchronous call from the service implementation, but I can't, because GWT services assume that you behave synchronously in service implementations. How can I work around this and make an asynchronous call from my service method implementation?
You are mixing up client and server side code. In ProxyServiceImpl, you CANNOT use RequestBuilder. RequestBuilder is a client side class which will only execute in the browser.
A server-to-server http call is always synchronous. Instead of using RequestBuilder, you should make use of a library like HttpClient, get the results and then send it back to the client. That would solve the problem you are facing.
But I should add, you DO NOT want to build a proxy at the application level. You could just as well use a http proxy such as apache's mod_proxy.