Techniques for RPC authentication - pros/cons

158 views
Skip to first unread message

joster

unread,
Nov 4, 2007, 11:31:33 AM11/4/07
to Google Web Toolkit
Dear All-

I have been digging into the archives for different techniques being
used for RPC authentication. So far, here is what I have found:

1) Store sessionId in database, send sessionId as RPC parameter to the
server-side code, query database to determine if sessionsId match and
not expired - handle exceptions accordingly

2) Some have used filters:
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/5d05a23a814200a6

My questions:
- When there are many RPC calls to the server, the additional penalty
of authenticating each RPC call can add-up? Are there ways to address
the run-time issue with authentication of RPC calls?
- Are there other ways to authenticate RPC calls?
- Is it possible to store the sessionId in a static class variable
(say in client or server side) and use that to do authentication of
RPC calls? Is this technique reliable?

Thanks in advance.

Joster

mP

unread,
Nov 4, 2007, 6:07:22 PM11/4/07
to Google Web Toolkit
If your server is a j2ee web container there is no need to store your
session id in a database. You could very well replace all yourdatabase
stuff with the http session.

On Nov 5, 3:31 am, joster <joster.j...@gmail.com> wrote:
> Dear All-
>
> I have been digging into the archives for different techniques being
> used for RPC authentication. So far, here is what I have found:
>
> 1) Store sessionId in database, send sessionId as RPC parameter to the
> server-side code, query database to determine if sessionsId match and
> not expired - handle exceptions accordingly
>
> 2) Some have used filters:

> http://groups.google.com/group/Google-Web-Toolkit/browse_thread/threa...

joster

unread,
Nov 4, 2007, 6:18:32 PM11/4/07
to Google Web Toolkit
Hi-

Thanks. I am using tomcat container for the server. Could you please
elaborate how to authenticate RPC calls with http session? Also, I
want to tie this to user authentication, so my sessionId is generated
at the time of login, I use the UUID generator for unique session id
at the time of login, once user pass login-check, I store the
sessionId in database.

Joster

Peter Blazejewicz

unread,
Nov 4, 2007, 8:05:27 PM11/4/07
to Google Web Toolkit
hi Joster,

maybe you could store UUID generated seeds in session object and use
it instead of session id to authenticate your user,
to hide interface complex you can use Delegate pattern,
example: (replace "sessionID" with "UUID" generated id while reading
example)


package com.mycompany.project.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;

public class MyServiceDelegate {
private static String sessionID;
private static MyServiceAsync instance;

//
MyServiceAsync getService() {
if (instance == null) {
instance = (MyServiceAsync) GWT.create(MyService.class);
ServiceDefTarget target = (ServiceDefTarget) instance;
target.setServiceEntryPoint(GWT.getModuleBaseURL() + "MyService");
}
return instance;
}

public void getUser(int userID, AsyncCallback callback) {
getService().getUser(sessionID, userID, callback);
}

public void getUsers(AsyncCallback callback) {
getService().getUsers(sessionID, callback);
}

public void login(String username, String password, AsyncCallback
callback) {
final AsyncCallback handler = callback;
getService().login(username, password, new AsyncCallback() {
public void onFailure(Throwable caught) {
handler.onFailure(caught);
}

public void onSuccess(Object result) {
sessionID = (String) result;
handler.onSuccess(result);
}
});
}

public void logout(AsyncCallback callback) {
getService().logout(sessionID, callback);
}

public void updateUser(User user, AsyncCallback callback) {
getService().updateUser(sessionID, user, callback);
}

public void validateSession(AsyncCallback callback) {
getService().validateSession(sessionID, callback);
}

}


public String login(String username, String password) {..}
on server should return your UUID (or simply session id which is also
unique),
in login response you can store uuid as field variable and resuse in
each next request:

public boolean updateUser(String sessionID, User user) {
if (isValidSession(sessionID)) {
return true;
}
throw new RuntimeException("Invalid session id");
}

called by delegate:

MyServiceDelegate delegate = new MyServiceDelegate();
delegate.updateUser(currentUser, myCallback);

so Delegate hides using sessions ids/uuid from your client code,

regards,
Peter

joster

unread,
Nov 4, 2007, 8:44:10 PM11/4/07
to Google Web Toolkit, Chad Bourque
Hi Peter-

Thanks for detailed code snippet, I am trying to understand how to use
this.
I got help from Chad (thanks much) how to create login/logout,
user authentication and handle subsequent RPC validation.
Outlined below are the steps received from Chad.

========================================================
1) The user loads the site and is presented with a login dialog
2) The user enters his username and password
3) Pass this information to the server via RPC either by creating
an object with fields for the username and password, or by
passing them as parameters to the RPC method
4) On the server, lookup the username in the database and verify
that the password matches (or encrypt the password and verify
that the encrypted password matches what is stored in the
database)
5) After passing the validation (password matches), generate an entry
in your sessions table (create one in your database containing
columns for the username, sessionID, and a timestamp at a bare
minimum)
6) The sessionID for the new row in the sessions table should be
generated by the server side -- most likely by the database server
itself as it will need to be unique in the sessions table (make it
the primary key of the table)
7) In the object you will return, add a field to hold the sessionID --
If you don't return an object, just return the sessionID as a
primitive
8) Create a class with a public static field that can hold the
sessionID after login
9) For ALL of the rest of you RPC calls, either add a sessionID
parameter to
the call or (if you are passing objects as the parameter) add a
sessionID
field to the object (the sessionID will be retrieved from your
class above
10) Now, with every RPC-callable method in your server-side code, you
first need
to take the sessionID, look it up in your sessions table and
make sure your
timestamp isn't too old
11) Also, when you do this, if it isn't too old, reset the timestamp
to the
current time
12) Now your session will last as long as the user is making server
calls plus
whatever time you determine will make the session too old (i.e.
5 min or 15
min or 8 hours -- whatever you want)
13) If the session is valid, you can do whatever that particular
method was supposed to do
14) If you need user-specific data, you can get the username from the
sessions table
15) If your app doesn't need to query for user-specific data, but only
needs user
validation, then you don't need to put the username in the
sessions table
========================================================

I am able to follow steps number 1 thru 8, now I am trying to figure
out how
to do step-9 and step-10.

My questions:
a) Are you suggesting, I use the delegate patter for step-9, so that I
don't have
to pass the sessionId with every RPC method? This would hide
passing
the sessionId with every RPC method, right?

b) Performance related question: to validate the session, I need to
look-up
(make a query to the database) for valid session - this is
additional query
for every RPC call.
I am wondering if this is the right approach. In my application, I
do have
lots of RPC calls and am concerned adding another query may
degrade
overall performance
Are there other techniques for validating session id without making
a
query to the database?
Step-11 will also require additional insert-call to the database.

Thanks in advance.

Joster

On Nov 4, 5:05 pm, Peter Blazejewicz <peter.blazejew...@gmail.com>
wrote:

Peter Blazejewicz

unread,
Nov 4, 2007, 11:06:06 PM11/4/07
to Google Web Toolkit
hi Joster,

you should distinct two different things in your topic:
#1
how to pass ids with RPC requests (e.g. sessions ids, other unique
data)
#2
how to implement session tracking backend,

What Miroslav wrote is that you can implement session tracking using
purely Servlet http session without a need for database (database is
required only to validate user credentials but not to handle sessions/
sessions timeouts)
What Chad wrote is description of session management based on database
tracking.
But it depends on your requirements and requirements for your project.
Basic session tracking can be solely based on Servlet api http session
and session timeouts. Just create session and save your UUID within
session object and each time user hits server check if UUID exist in
session and if session is not expired

Chad also wrote description of what I wrote in sample code:

have service implementation (RPC):
- each method accepts unique value (e..g session ID, uuid)
see my code above .e.g getService().updateUser(sessionID, user);

to hide that implementation details from your client side code write
delegate object which basically when you login for the first time
stores session id (or another UUID value) in static field - what Chad
described also) and on each other method use that identifier
internally,

I don't know what is better for performance reason: http servlet
session tracking or database session tracking, depends on systems and
requirements I think,

regards,
Peter

joster

unread,
Nov 4, 2007, 11:20:25 PM11/4/07
to Google Web Toolkit
Hi Peter-

Appreciate your help and thanks for explaining details. I am learning
lots!

> What Miroslav wrote is that you can implement session tracking using
> purely Servlet http session without a need for database (database is
> required only to validate user credentials but not to handle sessions/
> sessions timeouts)

> Basic session tracking can be solely based on Servlet api http session


> and session timeouts. Just create session and save your UUID within
> session object and each time user hits server check if UUID exist in
> session and if session is not expired

Could you please help, on how to do session tracking based on the
servlet
api http session? Is this using cookies, I did find some links:
http://www.apl.jhu.edu/~hall/java/Servlet-Tutorial/Servlet-Tutorial-Cookies.html

Or, are the simpler methods?

Joster

anubhava

unread,
Nov 4, 2007, 11:31:31 PM11/4/07
to Google-We...@googlegroups.com
Dear All,


I m very happy with your friendship and google help.
I cant imagined for this times because by helping of google there are lot of
software eng. Who r my friends.


Thanks
Anubhava Dimri
9250168195

Peter Blazejewicz

unread,
Nov 4, 2007, 11:33:36 PM11/4/07
to Google Web Toolkit
hi Joster,

you don't need to take care about cookies/url rewritint, etc, just
forget about manual handling of cookies/urls,
It's done behind-the-scene for us between client-server calls,
What we need to care is to pass unique "something" with Ajax-RPC calls
due to security reuqirements, that is that additional step required
compared to regular session handling and work with HttpSession within
servlet code,
Session is obtained in your server and it can be created/
invalidated(destroyed)/timed out (see servlet api about sessions),
here is basic sample from GWTiger library about using http session in
GWT RPC:
http://gwtiger.googlecode.com/svn/trunk/samples/GWTigerDemo/src/com/mycompany/server/MyAppServiceImpl.java

notice that example does not contain passing that additional "uniuqe"
seed which is something we are talking here (see my delegate class
description),

regards,
Peter

> http://www.apl.jhu.edu/~hall/java/Servlet-Tutorial/Servlet-Tutorial-C...

mP

unread,
Nov 5, 2007, 3:35:05 AM11/5/07
to Google Web Toolkit
Joster you have taken a simple problem and made it overly complicated
- KISS.

1. User loads page.
2. Show modal login dialogbox.
3. Verify submitted userid/password via loginService.
4. If credentials fail goto 2
5 Credentials ok hide logon dialog box show actual appl.

LoginService
Checks uid/password returning flag or exception with error message.
If credentials are ok store a dummy value in the session.

All other services are protected by a filter.
Filter
doFilter(){
if( session attribute doesnt have dummy value ){
throw exception complaining that user is not yet authenticated.
}

let filter chain continue...
}

joster

unread,
Nov 5, 2007, 4:12:39 AM11/5/07
to Google Web Toolkit
Thanks Miroslav for help. I will take your simpler approach.

Reinier Zwitserloot

unread,
Nov 5, 2007, 6:31:41 AM11/5/07
to Google Web Toolkit
Don't go to the database every trip; cache that stuff or,
alternatively, don't store that in the DB at all.

The latter will get in the way of replication and will force everyone
to log in again if you reset your server, though.

Reply all
Reply to author
Forward
0 new messages