gwt mvp sessions

561 views
Skip to first unread message

ernesto.reig

unread,
Jan 17, 2011, 5:11:09 AM1/17/11
to Google Web Toolkit
Hello everybody.
I´m trying to develop my first gwt mvp application following the
directions given in http://code.google.com/webtoolkit/doc/latest/DevGuideRequestFactory.html
I want to make a login page where the user has to log in before
entering to the main application view. Anyway, the thing is that I
have to implement the user sessions in the application and I would
like to know the best (the most recommended or professional) way.
I´ve been googling but I´m getting a bit lost since I don´t find a
clear solution. I found http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ
but I´m not sure if that´s the best way to do it.
I´d apprecciate every help.

Thank you very much.

junaid

unread,
Jan 17, 2011, 12:33:22 PM1/17/11
to google-we...@googlegroups.com
You need to put session code in server side
 
if you know the basics of session ,below code would be helpful 

HttpSession session;

session

= getThreadLocalRequest().getSession(true
);

save value in session:

session

.setAttribute("myuser", user);  [ myuser-- name of the session ]   [user- any object,string] 

get value from session:

session

.getAttribute("myuser");

cheers


--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.


ernesto.reig

unread,
Jan 17, 2011, 12:35:54 PM1/17/11
to Google Web Toolkit

Any comments please?

Y2i

unread,
Jan 17, 2011, 2:54:59 PM1/17/11
to google-we...@googlegroups.com
There are many ways to implement logins, depending on the server side you use.  

If you use servlets then the servlet spec will guide you: http://jcp.org/aboutJava/communityprocess/pr/jsr315/index.html

Look at <login-config/>, <auth-method/>, <realm-name/>, <security-role/>, <security-role/> tag description

Once web.xml is configured, you need to configure your realm.  This part is server-specific. 

If you use Jetty 6.1.x (the version embedded into GWT distribution), then look at org.mortbay.jetty.webapp.WebAppContext's securityHandler, which is configured in jetty-web.xml.
If you want to use JAAS for authentication and authorization, configure securityHandler with org.mortbay.jetty.plus.jaas.JAASUserRealm. 

JAASUserRealm itself requires module configuration.  If you want to use a datastore to keep user credentials, then conigure the module with org.mortbay.jetty.plus.jaas.spi.DataSourceLoginModule.

Other servers (including GAE) have their own settings, I'm just afraid I'm getting too specific here...

 
Message has been deleted

Y2i

unread,
Jan 17, 2011, 7:04:11 PM1/17/11
to google-we...@googlegroups.com
P.S. Forgot to mention that if you use GAE, it's better to start from this page.

Ernesto Reig

unread,
Jan 18, 2011, 4:43:12 AM1/18/11
to google-we...@googlegroups.com
Thank you very much for your responses.
So, in order to clarify things:
Is it better to use RequestFactory to "talk" to the server in every case? or is it better to use GWT RPC when the user first logs in (sending the credentials to the server and creating the session id) and RequestFactory for everything else?

Thank you.


Y2i

unread,
Jan 18, 2011, 11:27:42 AM1/18/11
to google-we...@googlegroups.com
It probably does not matter, RequestFactory is just a form of RPC.  You can have 2 request factories: one for login, anther for the rest of the app.

Ernesto Reig

unread,
Jan 18, 2011, 12:05:23 PM1/18/11
to google-we...@googlegroups.com
It does not make sense to have 2 RequestFactory(s) in a single web app. I´d have 2 (or more) RequestContext, and I´d get them having these methods in my AppRequestFactory interface (one of them dealing with the user management):

ARequest aRequest();
BRequest bRequest();

The question of having the session management with GWT RPC is because I was following these directions: http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ and I wonder how to implement session management (authentication/authorization) with RequestFactory.

Every help will be appreciated. Thanks.


Thomas Broyer

unread,
Jan 18, 2011, 12:28:03 PM1/18/11
to google-we...@googlegroups.com
If you want to pass an "authentication token" on each request, then the RequestTransport is the way to go on the client-side.

Have a look http://code.google.com/p/google-web-toolkit/source/browse/tags/2.1.1/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/ which is used in the Expenses sample.

However, if you want to do your login() call using RequestFactory, then you'd of course get rid of the servlet filter and then either add checks in each service method requiring authentication (not productive, but easy to comprehend) or somehow "filter" the invocations using a ServiceLayerDecorator (kind of AOP-like) that report() any unauthorized call. You'd probably couple that with a com.google.gwt.requestfactory.server.ExceptionHandler and generic error management in your Receiver subclasses (in onFailure).

I'm talking from experience: I'd highly recommend doing sign-in outside the app and use the approach used by the Expenses sample (though I acknowledge there are use-cases for "in app" authentication that people think are worth the trouble)

Ernesto Reig

unread,
Jan 18, 2011, 2:02:29 PM1/18/11
to google-we...@googlegroups.com
Thank you Thomas. I´ll have a look (and try to understand) the approach you´ve recommended (used in the Expenses sample).
What a coincidende today I´ve been reading a blog http://tbroyer.posterous.com/ Maybe you know it ;) Congratulations for your great posts.

Thank you very much.


Y2i

unread,
Jan 18, 2011, 4:48:38 PM1/18/11
to google-we...@googlegroups.com


On Tuesday, January 18, 2011 9:05:23 AM UTC-8, ernesto.reig wrote:
It does not make sense to have 2 RequestFactory(s) in a single web app. I´d have 2 (or more) RequestContext, and I´d get them having these methods in my AppRequestFactory interface (one of them dealing with the user management):
 
It does if you use declarative security combined with form-based authentication as described Servlet specification.  <form-login-config/> requires <form-login-page/> URL that un-authenticated users can access to perform authentication.

As I said earlier, there are many ways to implement authentication/authorization.  If you use GAE it's better to stick with what it offers.

Ernesto Reig

unread,
Jan 19, 2011, 4:19:01 AM1/19/11
to google-we...@googlegroups.com
Thank you Y2i. The thing is that I don´t use GAE. I´ve never used GAE actually. But, as I said in my first comment, I want to implement the authentication/authorization the best way (the most recommended/professional) to do it.
If you think, from your experience, that the best way is using GAE, I will.

Thank you very much again.


Ernesto Reig

unread,
Jan 19, 2011, 7:09:53 AM1/19/11
to google-we...@googlegroups.com
Ok. I´ve been having a look to GAE Authentication. And there are things I don´t understand well...
If you look at this page (http://code.google.com/p/gwt-gae-book/wiki/Authentication), which seems to be quite reliable, it clearly says "Although it's possible to develop App Engine applications with custom authentication (e.g. using your own username/password lookup, or by connecting to custom 3rd party web services), we'll focus on OpenID".
Well, the thing is that I do need custom authentication. I need to generate my own usernames and their corresponding passwords to log in. I don´t know how to do it with GAE, but as above mentioned, it said "it's possible to develop App Engine applications with custom authentication".
So the question is:
 - How do I implement custom authentication using GAE?
 - Can I use the approach used by the Expenses sample? If so, what do I have to change/customize?
 - Using App Engine, can I use my own MySQL tables (for users and other data)?

I know I´m a bit confused.
Thank you for your help.


Y2i

unread,
Jan 19, 2011, 10:52:08 AM1/19/11
to google-we...@googlegroups.com
Sorry if I was not clear, I didn't say it's the best to use GAE, it all depends on your requirements.  GAE is a web server where you deploy your application.  If you chose to deploy on GAE then it's better to use authentication offered by GAE.

Ernesto Reig

unread,
Jan 19, 2011, 12:04:29 PM1/19/11
to google-we...@googlegroups.com
Keeping on trying to fully understand GAE Authentication, with the Expenses example approach, I find these lines of code:

UserService userService = UserServiceFactory.getUserService();

...
if (!userService.isUserLoggedIn()) {
  ...
}


And now I get stuck into this.
 - What is that UserService? Ok, it´s the interface com.google.appengine.api.users.UserService.
 - But how does it work? How can it check if a user is logged in? where the hell does it get the users from?

Thank you in advance.

Y2i

unread,
Jan 19, 2011, 12:37:58 PM1/19/11
to google-we...@googlegroups.com
Take a look here

And then here (the first link will also point you here)

Also read the overview 

The overview explains how users are authenticated.  Once a user is authenticated, UserService will know about the user.

Ernesto Reig

unread,
Jan 21, 2011, 5:50:39 AM1/21/11
to google-we...@googlegroups.com
Ok. If I haven´t misunderstood (reading at http://code.google.com/appengine/docs/java/users/overview.html#Authentication_Options), you have three options to authenticate users with App Engine:
 - A Google Account
 - An account from an (my) Google Apps domain.
 - An OpenID identifier

BUT, if I wanted to use my custom authentication I couldn´t do it any of these three ways, could I? I mean, I don´t want to have my users forced to create a Google Account or an OpenID account. I just need to give my users a username and password (via paper) in order to allow them to login in the system. This is because most of the users will be people with zero-internet-knowldge and they will receive the username and password, which they will write in the login screen.
 - Is this possible using GAE Authentication?
 - Do I have missed anything?

Thank you very much.


Ernesto Reig

unread,
Jan 21, 2011, 6:25:53 AM1/21/11
to google-we...@googlegroups.com
Following my previous post...
what I need is to provide my users with username and password, and to have full control of the users that login in my application. I don´t want that everybody who has a google account or an openID identifier can do login. So, the question again:

 - Is this possible using GAE Authentication?

Thank you very much.


Y2i

unread,
Jan 21, 2011, 10:54:15 AM1/21/11
to google-we...@googlegroups.com
It sounds, based on the full control requirement, that you cannot deploy on GAE.

Ernesto Reig

unread,
Jan 21, 2011, 12:21:22 PM1/21/11
to google-we...@googlegroups.com
Thank u for your help and comments Y2i (and the others).
To sum up, I will say that Google App Engine is a great thing to use with your apps, but it´s designed for apps where everybody having an openID account can log in, I mean, you cannot have your custom authentication.
- You cannot have your app using GAE for private purposes with your private users (unless your users have a Google Apps account, which is too expensive (50$/user)).
- You cannot restrict the access to everybody, allowing only a set of users (your clients, employees, etc) with a username and password that you provide.
This is a very common feature for web applications which is not considered in GAE. I would like  to have my private web app (with my private users) hosted in GAE, and pay for that as the numbers of new users I register grows.
Well, I´ll post my final solution for the authentication (maybe a common one), but it´s a pity I cannot use GAE :(

Thank you.


Ernesto Reig

unread,
Jan 21, 2011, 12:36:26 PM1/21/11
to google-we...@googlegroups.com
I forgot to say this in my previous message:
I don´t think that including the Expenses app in the distribution of GWT is a good idea. I ONLY SAY THIS BECAUSE OF THE AUTHENTICATION APPROACH USED. I mean, it seems to be a custom app for a private organization/company. But as said in my previous comment, you cannot use custom authentication. And I don´t think a company would like to have its expenses and reports available to the world (using google accounts or openID).
The only way it is justified would be if the authentication used in GAE in the Expenses app was using the accounts from a Google Apps domain for the users of a given company. Which I think it should be explained or commented in the application.

I would appreciate any comment about this.
Thank you again.


Ernesto Reig

unread,
Jan 24, 2011, 11:33:45 AM1/24/11
to google-we...@googlegroups.com
Someone to deny or confirm my two previous comments on this post?

Thank you.


Ernesto Reig

unread,
Jan 26, 2011, 5:52:10 AM1/26/11
to google-we...@googlegroups.com
Thomas, just to know an expert opinion. How would you implement the custom authentication? I mean, not using GAE.

Thank you in advance.


Thomas Broyer

unread,
Jan 26, 2011, 8:53:09 AM1/26/11
to google-we...@googlegroups.com
You mean how I did implement it? ;-)

Using the same pattern as the Expenses sample:
  1. out HTML host page (the one calling the *.nocache.js) is protected with a simple servlet FORM authentication (<login-config><auth-method>FORM</...> in the web.xml); nothing special here.
  2. the server returns a known error response for unauthenticated requests (i.e. a 401 status code, I didn't include a WWW-Authenticate header which is in violation of HTTP, but it just works so...), this is done in a servlet Filter, where I simply check for request.getUserPrincipal() != null. This has really nothing specific to RequestFactory, and we use it with other XMLHttpRequest-driven requests too.
  3. the client handles the known error response in a custom RequestTransport (in our case, for the time being, we simply Window.alert() the user, prompting him to refresh the page to re-authenticate)

(BTW, thank you for the "expert" qualifier ;-) )

Ernesto Reig

unread,
Jan 26, 2011, 1:53:56 PM1/26/11
to google-we...@googlegroups.com
Thank you very much for your response Thomas. I´ve reading and reading about the servlet authentication and I was going to ask you some more things about this approach, but I can´t sort my ideas now hehe. I´ll carry on this tomorrow :)

Thank you again.


Ernesto Reig

unread,
Jan 27, 2011, 10:03:32 AM1/27/11
to google-we...@googlegroups.com
Hello again.
It seems that I get stuck in every step... The thing is that I don´t know how to use Tomcat for the Development Mode instead of the embedded Jetty. I´ve been reading lots and lots of docs (including http://code.google.com/webtoolkit/doc/latest/DevGuideCompilingAndDebugging.html#How_do_I_use_my_own_server_in_development_mode_instead_of_GWT%27s) but I still haven´t found a way to do it. In my opinion it isn´t well explained at al, it´s very unclear...
I have arrived to this because, as you said, protecting the host page with a "servlet FORM authentication" forces me to use Tomcat.
So I need to check that the servlet authentication I am implementing is right. Therefore, I have to deploy my webapp in Tomcat, BUT I don´t want to end up re-deploying the application in Tomcat every time I make a little change in the code.

Any help on this, please?

Than you very much.


Y2i

unread,
Jan 27, 2011, 10:09:52 AM1/27/11
to google-we...@googlegroups.com
I also started from using Tomcat, but the debugging issue forced me to switch to Jetty.  It took time to learn Jetty's specifics but it was worth it.

Ernesto Reig

unread,
Jan 27, 2011, 1:14:29 PM1/27/11
to google-we...@googlegroups.com
Thank you very much for your response. At the moment I´m studying jetty and I get to a very simple question:
¿What is or how can I know, the current Jetty version of the current GWT version? Now I´m using 2.1.1
This is a very simple question that I cannot understand why in the world there´s no answer in the GWT official documentation...

Thank you in advance.




Ernesto Reig

unread,
Jan 27, 2011, 1:49:01 PM1/27/11
to google-we...@googlegroups.com
Ok. Now I´m configuring the application to authenticata against the embedded Jetty server wich comes with GWT. Please, correct me if I´m wrong:
 - I have to create a jetty-web.xml in WEB-INF of my gwt application with the following text:

<Configure class="org.mortbay.jetty.webapp.WebAppContext">
  <Set name="contextPath">/test</Set>
  <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test</Set>
   ...
  <Get name="securityHandler">
    <Set name="userRealm">
      <New class="org.mortbay.jetty.security.HashUserRealm">
        <Set name="name">Test Realm</Set>
        <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
      </New>
    </Set>
  </Get>
</Configure>

And it gives me the following exception:
java.io.FileNotFoundException: C:\workspace\myapp\src\main\webapp\etc\realm.properties (The system cannot find the path specified)
Of course it does not find the file realm.properties. First, I have no jetty.home system variable set, and second, what would it be the value of this system variable??
The thing is, if I want to use HashUserRealm for my webapp authentication, Jetty looks for a properties file to find the users and their credentials, but where the hell is that file? Jetty is embedded...

Maybe I´m wrong in something. Please help.

Thomas Broyer

unread,
Jan 27, 2011, 2:21:21 PM1/27/11
to google-we...@googlegroups.com


On Thursday, January 27, 2011 7:49:01 PM UTC+1, ernesto.reig wrote:
Ok. Now I´m configuring the application to authenticata against the embedded Jetty server wich comes with GWT. Please, correct me if I´m wrong:
 - I have to create a jetty-web.xml in WEB-INF of my gwt application with the following text:

<Configure class="org.mortbay.jetty.webapp.WebAppContext">
  <Set name="contextPath">/test</Set>
  <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test</Set>

You don't have to set these: you're already in the webapp (I don't think the contextPath will be used given the way the webapp is deployed)

   ...
  <Get name="securityHandler">
    <Set name="userRealm">
      <New class="org.mortbay.jetty.security.HashUserRealm">
        <Set name="name">Test Realm</Set>
        <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
      </New>

The "jetty.home" points to your working directory (according to my comment in http://code.google.com/p/google-web-toolkit/issues/detail?id=4462), which generally will be your "war" folder.

(compared to the sample jetty-web in my comment on the issue, you would just need to replace the "authenticator" with the <login-config>, or you could use the same thing as I used to use)

Y2i

unread,
Jan 27, 2011, 2:57:19 PM1/27/11
to google-we...@googlegroups.com
Based on the below I assumed it's 6.1.23, this is what I'm using.

find . -name "*jetty*"
./org.eclipse.equinox.http.jetty_2.0.0.v20100503.jar
./org.mortbay.jetty.serveradaptor_1.0.4
./org.mortbay.jetty.serveradaptor_1.0.4/icons/jetty_tiny.gif
./org.mortbay.jetty.serveradaptor_1.0.4/servers/jetty.serverdef
./org.mortbay.jetty.server_6.1.23.v201004211559.jar
./org.mortbay.jetty.util_6.1.23.v201004211559.jar

Thomas Broyer

unread,
Jan 27, 2011, 8:39:05 PM1/27/11
to google-we...@googlegroups.com
Jetty classes are packaged within gwt-dev.jar, that one comdes from somewhere else (Eclipse WTP ?)

Thomas Broyer

unread,
Jan 27, 2011, 8:40:13 PM1/27/11
to google-we...@googlegroups.com
Oops, sorry: 6.1.11 (but you'd have clicked the link to get the authoritative answer, right? ;-) )

Y2i

unread,
Jan 27, 2011, 11:13:10 PM1/27/11
to google-we...@googlegroups.com
thank you very much for the link.  So I've been using a wrong version all along...

Ernesto Reig

unread,
Jan 28, 2011, 5:24:43 AM1/28/11
to google-we...@googlegroups.com
Thank you very much for your responses Thomas and Y2i.

Maybe, this can help to other people who are (like me) changing from Tomcat to Jetty. Refering to the web.xml and jetty-web.xml:

 - I did know that jetty.home was pointing to my working directory (C:\workspace\my_app\src\main\webapp in my case), but my problem was that I couldn´t understand that Jetty was going to look for the users in a properties file inside my_app. I was trying to draw an analogy between the tomcat-way and the Jetty-way. I though "if the authentication is against the server (jetty), why do I have to provide the users to Jetty?" And the answer to this question is that this properties file is used to authenticate users ONLY for THIS web application.
For Tomcat users: it´s like configuring a realm inside a <Context> element (http://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html#Configuring_a_Realm).

I presume that in a real context, you can have the properties file inside your_app, or establish the jetty.home system property and point to the properties file inside jetty.home/etc/realm.properties and authenticate as a user shared in all web apps.

Ernesto Reig

unread,
Feb 16, 2011, 6:14:21 AM2/16/11
to google-we...@googlegroups.com
On 26 January 2011 14:53, Thomas Broyer <t.br...@gmail.com> wrote:
You mean how I did implement it? ;-)

Using the same pattern as the Expenses sample:
  1. out HTML host page (the one calling the *.nocache.js) is protected with a simple servlet FORM authentication (<login-config><auth-method>FORM</...> in the web.xml); nothing special here.
  2. the server returns a known error response for unauthenticated requests (i.e. a 401 status code, I didn't include a WWW-Authenticate header which is in violation of HTTP, but it just works so...), this is done in a servlet Filter, where I simply check for request.getUserPrincipal() != null. This has really nothing specific to RequestFactory, and we use it with other XMLHttpRequest-driven requests too.
I don´t know why this is wrong, but the checking of request.getUserPrincipal() != null seems to be valid only the first time a request is made. The following requests (made by the requestFactory), getUserPrincipal() returns null. Here´s my code in my AuthFilter class:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  HttpServletRequest request = (HttpServletRequest) servletRequest;
  HttpServletResponse response = (HttpServletResponse) servletResponse;

  if(request.getUserPrincipal() == null) {
    response.setHeader("WWW-Authenticate", "FORM realm=\"userRealm\"");
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    return;
}
 
What am I doing wrong?
  1. the client handles the known error response in a custom RequestTransport (in our case, for the time being, we simply Window.alert() the user, prompting him to refresh the page to re-authenticate)

(BTW, thank you for the "expert" qualifier ;-) )

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.


Ernesto Reig

unread,
Feb 16, 2011, 7:03:11 AM2/16/11
to google-we...@googlegroups.com
On 16 February 2011 12:14, Ernesto Reig <erni...@gmail.com> wrote:


On 26 January 2011 14:53, Thomas Broyer <t.br...@gmail.com> wrote:
You mean how I did implement it? ;-)

Using the same pattern as the Expenses sample:
  1. out HTML host page (the one calling the *.nocache.js) is protected with a simple servlet FORM authentication (<login-config><auth-method>FORM</...> in the web.xml); nothing special here.
  2. the server returns a known error response for unauthenticated requests (i.e. a 401 status code, I didn't include a WWW-Authenticate header which is in violation of HTTP, but it just works so...), this is done in a servlet Filter, where I simply check for request.getUserPrincipal() != null. This has really nothing specific to RequestFactory, and we use it with other XMLHttpRequest-driven requests too.
I don´t know why this is wrong, but the checking of request.getUserPrincipal() != null seems to be valid only the first time a request is made. The following requests (made by the requestFactory), getUserPrincipal() returns null. Here´s my code in my AuthFilter class:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  HttpServletRequest request = (HttpServletRequest) servletRequest;
  HttpServletResponse response = (HttpServletResponse) servletResponse;

  if(request.getUserPrincipal() == null) {
    response.setHeader("WWW-Authenticate", "FORM realm=\"userRealm\"");
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    return;
}
 
What am I doing wrong?

Sorry, it was my fault. I have it solved :)


veenatic

unread,
Feb 24, 2011, 4:49:02 PM2/24/11
to google-we...@googlegroups.com
If you want to pass an "authentication token" on each request, then the RequestTransport is the way to go on the client-side.

Have a look http://code.google.com/p/google-web-toolkit/source/browse/tags/2.1.1/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/ which is used in the Expenses sample.

Hi Thomas,
Thanks for all your valuable insight to the subject.
I am looking for some more explanation on the above. If I understood correctly, we can implement separate page for login and a separate page where the gwt app resides. Once the user is authenticated from login page, we have the "security token", but how to communicate the token obtained from the login page to the gwt app so that we can put the token in the RequestTransport and initialize the RequestFactory.

Thomas Broyer

unread,
Feb 24, 2011, 6:19:02 PM2/24/11
to google-we...@googlegroups.com
In such a scenario, you'll generally have a "session" maintained by the server through a cookie, which will be enough (yes, cookies are not that secure, but still deemed secure enough that everyone from Google to Facebook, Twitter, Microsoft, Yahoo!, etc. use them). The RequestTransport will then be useful to detect when the session/cookie have expired.

Now, if your "host page" (the page that "hosts" the GWT app) can now an authentication token, then you can output it in the page (using a JSP for instance) and use a Dictionary to retrieve it from your GWT code.

Jeff Schwartz

unread,
Feb 24, 2011, 7:49:17 PM2/24/11
to google-we...@googlegroups.com
On Thu, Feb 24, 2011 at 6:19 PM, Thomas Broyer <t.br...@gmail.com> wrote:
In such a scenario, you'll generally have a "session" maintained by the server through a cookie, which will be enough (yes, cookies are not that secure, but still deemed secure enough that everyone from Google to Facebook, Twitter, Microsoft, Yahoo!, etc. use them).

I respectfully disagree, Thomas, and think your advice on this is ill served. In addition I believe that there are those at all the companies that you mentioned who would take issue with your opinion. Values from cookies that are explicitly maintained on the client and which are transported to the server as part of an RPC's  payload can be trusted but values which come directly from HTTPRequest's cookies aren't trustworthy. That's a fact. Leave one little hole open and some malcontent with a half a brain is going to take advantage of it and hijack your session. It's such an easy prevention to implement that one would have to be foolish to not take advantage of it.

--
Jeff Schwartz
http://jefftschwartz.appspot.com/
http://www.linkedin.com/in/jefftschwartz
follow me on twitter: @jefftschwartz

Thomas Broyer

unread,
Feb 25, 2011, 8:49:32 AM2/25/11
to google-we...@googlegroups.com
Of course! I didn't mean to imply that you shouldn't secure your app, but honestly if someone succeeds in hijacking your session, then he could possibly do it before loading the host page, so that your GWT app will run with the hijacked session, and the "auth token in the request payload" won't be of any help.

Jeff Schwartz

unread,
Feb 25, 2011, 9:21:18 AM2/25/11
to google-we...@googlegroups.com
Hi Thomas,

On Fri, Feb 25, 2011 at 8:49 AM, Thomas Broyer <t.br...@gmail.com> wrote:
Of course! I didn't mean to imply that you shouldn't secure your app, but honestly if someone succeeds in hijacking your session, then he could possibly do it before loading the host page, so that your GWT app will run with the hijacked session, and the "auth token in the request payload" won't be of any help.

First off, the hacker couldn't have access to the local cookie on the user's machine unless the user has been infected with a virus. If the user's computer has been infected with a virus that can some how target local cookies then this user has a lot more to worry about than someone hijacking their session. So let's rule that scenario out.

Secondly, if the hacker could somehow manage to hijack your session - meaning they've some how coerced the request to use a different value for the session id) and do it before loading the host page it wouldn't make a difference if every Servlet method that is called does the following:
1) checks each payload for an auth token (a value equal to the sid stored as a cookie on the client) and
2) compares the auth token's value to the HttpSession's session id value. If they aren't the same then throw a custom exception and catch it on the client and authenticate the user (either form-based auth or some other method such as Google Account, OpenId, et. al)

Not only does the above protect against session hijacking but it also solves the "how do I know if the session is timed out" question. So you solve two use cases in one implementation which isn't bad.

You can even use filters to do this eliminating the need for every Servlet method to implement this logic.

It's a simple, viable solution to an attack that is quite prevalent these days. It's implementation on both the client and server are trivial yet (I would venture to guess) is regrettably ignored by many if not most developers (to which I am not limiting to GWT developers).

Of course, having a secure transport protocol (ie SSL) is the ultimate solution but not every site or every page on a site requires SSL yet every page that communicates with the server on every site requires a proactive defense against these kinds of attacks.
 
--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

veenatic

unread,
Feb 25, 2011, 10:14:32 AM2/25/11
to google-we...@googlegroups.com
Does this mean that "auth token" in the request payload is not of much use?
Also, I want to understand when i have the token set in the requestfactory payload, how to retrieve from the payload when a service call is made by requestfactory since i will have to validate the token for every service request.

Jeff Schwartz

unread,
Feb 25, 2011, 10:50:10 AM2/25/11
to google-we...@googlegroups.com

To the contrary - it means that every request to the server should include it and that ever request should validate it against the HttpSession's session id value and respond accordingly.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Thomas Broyer

unread,
Feb 25, 2011, 11:38:10 AM2/25/11
to google-we...@googlegroups.com


On Friday, February 25, 2011 3:21:18 PM UTC+1, Jeff wrote:
Hi Thomas,

On Fri, Feb 25, 2011 at 8:49 AM, Thomas Broyer <t.br...@gmail.com> wrote:
Of course! I didn't mean to imply that you shouldn't secure your app, but honestly if someone succeeds in hijacking your session, then he could possibly do it before loading the host page, so that your GWT app will run with the hijacked session, and the "auth token in the request payload" won't be of any help.

First off, the hacker couldn't have access to the local cookie on the user's machine unless the user has been infected with a virus. If the user's computer has been infected with a virus that can some how target local cookies then this user has a lot more to worry about than someone hijacking their session. So let's rule that scenario out.

I can setup an web page at attacker.appspot.com that sets a cookie with Domain=.appspot.com, and it'll target every appspot.com app out there. If victim.appspot.com uses its own authentication mechanism and its own cookies, I can then easily set a cookie to a user's browser visiting attacker.appspot.com and redirect it to victim.appspot.com, and he would then be automatically authenticated with my own session (session fixation attack).
 
Secondly, if the hacker could somehow manage to hijack your session - meaning they've some how coerced the request to use a different value for the session id) and do it before loading the host page it wouldn't make a difference if every Servlet method that is called does the following:
1) checks each payload for an auth token (a value equal to the sid stored as a cookie on the client) and
2) compares the auth token's value to the HttpSession's session id value. If they aren't the same then throw a custom exception and catch it on the client and authenticate the user (either form-based auth or some other method such as Google Account, OpenId, et. al)

But if the auth token is initialized from the cookie (or somehow attached to the authenticated user) and the attacker managed to set the cookie value on behalf of the webapp (or at least do a session fixation attack), then those two checks won't detect it.

Jeff Schwartz

unread,
Feb 25, 2011, 12:10:14 PM2/25/11
to google-we...@googlegroups.com
You are talking about using request cookies so of course the scenario you describe might be possible. Everyone knows they are vulnerable and hence their ease of hijacking. The right way to do it is not using request cookies at all on the server because they cannot be trusted - the auth token must be delivered to the server as part of the payload and it must never be read from a request cookie.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Thomas Broyer

unread,
Feb 25, 2011, 12:30:03 PM2/25/11
to google-we...@googlegroups.com
You contradict yourself (compare the HttpSession's ID with the auth token –the HttpSession is maintained by a cookie, whose value generally is the session's ID– vs. do not send the auth token in a cookie), but that's not the problem.

The problem is: how are you initializing the auth token on the client side, and how you associate it with the user on the server-side? The client and server have to share some knowledge at some point, and if you have use "form based" authentication on another web page (i.e. your app's host page is protected and cannot be accessed without being authenticated), then the only way (not accurate, but that's how 99.999% of auth is done, because the alternative comes with a UX penalty) to "transfer" the authentication from the login page to the app's page is to use either a cookie or pass a unique token in the URL, both of which can be hijacked.

Jeff Schwartz

unread,
Feb 25, 2011, 12:39:40 PM2/25/11
to google-we...@googlegroups.com
On Fri, Feb 25, 2011 at 12:30 PM, Thomas Broyer <t.br...@gmail.com> wrote:
You contradict yourself (compare the HttpSession's ID with the auth token –the HttpSession is maintained by a cookie, whose value generally is the session's ID– vs. do not send the auth token in a cookie), but that's not the problem.

Actually I am not contradicting myself, Thomas. You just failed to understand!

The problem is: how are you initializing the auth token on the client side, and how you associate it with the user on the server-side? The client and server have to share some knowledge at some point, and if you have use "form based" authentication on another web page (i.e. your app's host page is protected and cannot be accessed without being authenticated), then the only way (not accurate, but that's how 99.999% of auth is done, because the alternative comes with a UX penalty) to "transfer" the authentication from the login page to the app's page is to use either a cookie or pass a unique token in the URL, both of which can be hijacked.

If the user is authenticated the authentication process should then send down the HttpSession id as part of the payload back to the client. The client then stores the session id it receives as part of the payload from the server as a local cookie. Encryption can even be applied on the server for extra security as it's value has no real meaning to the client, only that it needs to include it in each payload to the server.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Thomas Broyer

unread,
Feb 25, 2011, 2:20:36 PM2/25/11
to google-we...@googlegroups.com


On Friday, February 25, 2011 6:39:40 PM UTC+1, Jeff wrote:


On Fri, Feb 25, 2011 at 12:30 PM, Thomas Broyer <t.br...@gmail.com> wrote:
You contradict yourself (compare the HttpSession's ID with the auth token –the HttpSession is maintained by a cookie, whose value generally is the session's ID– vs. do not send the auth token in a cookie), but that's not the problem.

Actually I am not contradicting myself, Thomas. You just failed to understand!

And the other way around! ;-)

The problem is: how are you initializing the auth token on the client side, and how you associate it with the user on the server-side? The client and server have to share some knowledge at some point, and if you have use "form based" authentication on another web page (i.e. your app's host page is protected and cannot be accessed without being authenticated), then the only way (not accurate, but that's how 99.999% of auth is done, because the alternative comes with a UX penalty) to "transfer" the authentication from the login page to the app's page is to use either a cookie or pass a unique token in the URL, both of which can be hijacked.

If the user is authenticated the authentication process should then send down the HttpSession id as part of the payload back to the client. The client then stores the session id it receives as part of the payload from the server as a local cookie.

This is where you fail to understand me: you make the assumption that the "authentication process" takes place, while I'm talking about bypassing it with a session-fixation attack.

One possible scenario (easily mitigated through the use of your own domain name):
Attacker: authenticates to victim.example.com, grabs the cookies in use, store them at attacker.example.com (note: same domain, different subdomains, much like appspot.com hosted apps)
Victim: goes to attacker.example.com, which sets the cookies with Domain=.example.com and redirects it to victim.example.com
The victim's browser sends the cookies to victim.example.com (because of Domain=.example.com, they apply, even though they've been set by attacker.example.com)
The victim is then authenticated to victim.example.com with the same session as the attacker.
The session id is sent down to the client as part of the payload, but it's too late.

Jeff Schwartz

unread,
Feb 25, 2011, 4:34:04 PM2/25/11
to google-we...@googlegroups.com
I am not dismissing your scenarios outright as I never said that the method was foolproof and I also said that only SSL will give you something close to that.

Also lets not forget that if the user manages to be lured to an attackers site via a link in an email for instance and then doesn't notice that they are then redirected to another site then they have bigger problems than having their session hijacked lol.

However, there are ways to mitigate even the cross-subdomain attack that you use as an example...


On Fri, Feb 25, 2011 at 2:20 PM, Thomas Broyer <t.br...@gmail.com> wrote:
This is where you fail to understand me: you make the assumption that the "authentication process" takes place, while I'm talking about bypassing it with a session-fixation attack.

I understood perfectly, Thomas. To reiterate, the attacker will have had to authenticate in order to acquire a valid sid which he then stores and waits in prey for the user to respond to his email with a link to his site. When the user takes the bait and visits the attacker's site the attacker redirects the user to another site including the sid as a query parameter. 

One possible scenario (easily mitigated through the use of your own domain name):
Attacker: authenticates to victim.example.com, grabs the cookies in use, store them at attacker.example.com (note: same domain, different subdomains, much like appspot.com hosted apps)

At this point the request hits the server and the session id is set the query parameter, the same one as the attackers. This attack can be mitigated by changing the session ID when users logs in and to additionally require the user to authenticate on every important request. A pain in the rear for the user of course but it will largely work. The fact that it does work is due to the reluctance to require users to log in for every important request.

Sure enough, even if you used SSL it would require that every request uses it in order to be close to 100% protected from this kind of attack. The only sites I know that do that are some banks. I believe Citibank does for instance. Interestingly I believe Facebook announced that they will be rolling this out to all their members. It will be interesting to see how it affects the performance of their site.

Perhaps requiring every one to use SSL for every request is the right approach. Maybe we should all be going in that direction but service providers might be loathe to provide this service as it adds additional demands on their servers that they might not be able to handle and the users might complain because of the increased latency.

Perhaps using HttpOnly headers would also mitigate this kind of attack. I don't think App Engine supports it though but I wish it did.

The bottom line is this, it really comes down to a multi-faceted approach to security. One big wall isn't going to cut it and the more obstacles put up the less chances are that some malcontent will be successful.

veenatic

unread,
Feb 25, 2011, 7:01:56 PM2/25/11
to google-we...@googlegroups.com
I think the discussion has become very interesting and I understood a lot about attacks and attackers but I still ponder over the question that if we have to put the auth token on the payload of the RequestFactory, how to do that?
And after this how to read the token from the payload to verify it?

Jeff Schwartz

unread,
Feb 25, 2011, 7:15:06 PM2/25/11
to google-we...@googlegroups.com
With RPC I define all my RPC synchronous methods taking  a string parameter whose value will be assigned from the cooke storing the sid. On the server, the handler will compare this string value to the value returned from the Session.getId() method. If they aren't the same I throw a custom exception which is caught on the client in the overloaded OnFailure method of the RPC call.

Here's the typical code for a server-side handler:

    @Override
    public SingleRPCPayload<SomeTyoe> someMethod(String clientSid, ...) throws MyCapabilityDisabledException {
        HttpSession session = getThreadLocalRequest().getSession(true);
        String sid = session.getId();
        if (clientSid.equals(sid)) {
            .
            .
            .
            return payload;
        } else {
            throw new MyInvalidSessionException();
        }
    }
 

On Fri, Feb 25, 2011 at 7:01 PM, veenatic <praveen...@gmail.com> wrote:
I think the discussion has become very interesting and I understood a lot about attacks and attackers but I still ponder over the question that if we have to put the auth token on the payload of the RequestFactory, how to do that?
And after this how to read the token from the payload to verify it?

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Jeff Schwartz

unread,
Feb 25, 2011, 7:16:49 PM2/25/11
to google-we...@googlegroups.com
btw my bad I meant to say overridden OnFailure method... sorry about that

veenatic

unread,
Feb 25, 2011, 7:34:16 PM2/25/11
to google-we...@googlegroups.com
Thanks Jeff,
With RPC, this way is understood. Similarily, I have some idea with RequestFactory also like

requestFactory.serviceRequest().getAllEntities(clientSid);

and on the server side, in getAllEntities(String clientSid) i can verify the same way you did.

But this way is forcing me to put an extra parameter in all my business methods. I am sure there are other ways. Any Ideas?
Obviously, the above approach is not that ugly.

David Chandler

unread,
Feb 25, 2011, 7:50:10 PM2/25/11
to google-we...@googlegroups.com
You could use the Command pattern as with GWT-RPC using a ValueProxy as the command object, but I'm not sure what you'd gain by it as you'd lose all the RF functionality related to entities. As it currently stands, you would need to modify the RF transport protocol, perhaps with a ServiceLayerDecorator. Are you convinced that the token needs to be part of the payload vs. request header? It's much easier to modify the header by extending DefaultRequestTransport as Thomas has pointed out elsewhere.

/dmc

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.



--
David Chandler
Developer Programs Engineer, Google Web Toolkit
w: http://code.google.com/
b: http://googlewebtoolkit.blogspot.com/
t: @googledevtools
Reply all
Reply to author
Forward
0 new messages