Advice on abstracting authentication information into a superclass

64 views
Skip to first unread message

Ravi M

unread,
Jan 17, 2010, 1:36:12 PM1/17/10
to GWT Dispatch
I'm starting to play around with gwt-dispatcher and have the following
question. I have several actions GetFoo, GetBar etc. defined in my
application. Every time I want to perform an action on the server, I
also want to make sure that the browser session requesting the action
is authentic, valid etc. and for this in addition to whatever data is
needed for the action, I pass a token (say AuthToken) to the server
(which I've previously created by doing a login op on the server).

I can do

public class GetFoo implements Action<GetFooResult> {
private String id;
private AuthToken authToken;

public GetFoo( String id , AuthToken authToken) {
this.id = id;
this.authToken = authToken;
}
... etc.

Since I have to do this in every Action, I'd rather put this sort of
thing in an abstract superclass for all Actions, for easier
maintainability etc. I'd appreciate some pointers on how best to do
this? Is there some way I can define the parent class so that when
instantiating the child, I'm _forced_ to make sure that the AuthToken
is set etc.

Thanks and regards
Ravi

Syntax

unread,
Jan 18, 2010, 10:04:59 PM1/18/10
to GWT Dispatch
As far as I'm concerned your spot on.

1) Make your class abstract
2) Ensure you provide the constructor which takes both id and auth
token; all derived classes will be required to provide the same
constructor.
3) Annotate the id and authToken members with @NonNull (from Findbugs)

I use the above solution and it works perfectly. I called my
superclass SecureAction<Result>...

David Peterson

unread,
Jan 18, 2010, 10:42:58 PM1/18/10
to gwt-di...@googlegroups.com
Hi Ravi,

Sorry for the delay. The approach I've taken in the API is to have different implementations of the DispatchService. There is the StandardDispatchService, which has no security built in, or the SecureDispatchService, which is passed both an ID (provided by you) and the Action being performed. The SecureDispatchServiceServlet on the other end will then check that ID before executing the Action as per normal.

So, in code, you need to do the following:

Client:
1. SecureDispatchAsync: Implementation of DispatchAsync, which you actually use in your code.
2. SecureDispatchService/SecureDispatchServiceAsync: The actual RPC interface, used by SecureDispatchAsync
3. SecureSessionAccessor: This interface is used by SecureDispatchService to retrieve the 'security token' for the application. You need to provide an implementation to retrieve the appropriate token for your app. The 'CookieSecureSessionAccessor' might be a useful class - it grabs the ID from a specific cookie value. If you're using GAE, the 'AppEngineSecureSessionAccessor' would work.

Server:
1. A servlet implementing SecureDispatchServiceAsync. The 'AbstractSecureDispatchServlet', GuiceSecureDispatchServlet, or SpringSecureDispatchServlet may be useful here, depending on your context.
2. SecureSessionValidator: An implementation of this interface must be provided if you're using 'AbstractSevureDispatchServlet' or subclasses. It will do the actual test to check if the ID is valid.

If you're using GIN/Guice, there are a couple of support modules to make life a little simpler. You will need something like this:

Client:
1. MySecureDispatchModule:

public class MySecureDispatchModule extends SecureDispatchModule {
public MySecureDispatchModule() {
super( MyExceptionHandler.class );
}

@Override
protected void configure() {
super();
bind( SecureSessionAccessor.class ).to( MySecureSessionAccessor.class );
}
}

2. Install 'MySecureDispatchModule' in your GInjector.

Server:

1. MySecureModule

public class MySecureValidatorModule extends AbstractModule {
@Override
protected void configure() {
bind( SecureSessionValidator.class ).to( MySecureSessionValidator.class );
}
}

2. Install 'MySecureValidatorModule' and 'ServerDispatchModule'.

Easy, right? Ok, not so much....sorry about that.

David

Syntax

unread,
Jan 19, 2010, 3:37:03 AM1/19/10
to GWT Dispatch
I much prefer your dispatch service solution to the one I have in
place, It reduces obfuscation on the Action classes and removes the
need for each handler to validate the security model itself before
executing! :)

I am currently only using published artifacts for dispatch and
presenter.

After reading your post I have reviewed the trunk and can see your
secure dispatch service work, very nice! Any idea on when the next
release of Dispatch will be made?

Ravi M

unread,
Jan 19, 2010, 12:12:25 PM1/19/10
to GWT Dispatch
Thanks for your replies David and Syntax. Truth be told, I'm still
wading my way around Guice and GIN, so will need a little time to
absorb and make sense of it all. Initially I wasn't even planning to
use Guice on the server, I was going to use the framework provided by
gwt-dispatch to model Actions, Results, and ActionHandlers and write
my own servlet to handle the RPCs on the server, more in the interest
of getting something working out of the door sooner rather than later,
but it looks like I do need to take a full-fledged leap into the
dependency injection world. I hope it isn't rocket science, gulp :-)

The other problem I'm facing is that I haven't really used generics in
any non-trivial way (other than in parameterizing Collections and
Maps), so am trying to wrap my mind around the whole how-to-abstractly-
implement-interfaces-which-take-type-parameters and then extend-the-
abstract-class sort of stuff. Am stuck at the moment, but am sure I
can figure things out with a little bit of time, which unfortunately I
don't have too much of!

Anyway, I'll post back on this thread if I'm really marooned, maybe
with code snippets that you guys can make sense of.

Thanks again,
Ravi

Ravi M

unread,
Jan 19, 2010, 11:55:28 PM1/19/10
to GWT Dispatch
One further question: Does using gwt-dispatch and/or Guice impact
one's ability to debug server side code in an IDE? Any implications
there?

Thanks
Ravi

David Peterson

unread,
Jan 20, 2010, 12:29:33 AM1/20/10
to gwt-di...@googlegroups.com
No, debugging works great. You might want to link your IDE to the gwt-dispatch source code though.

David

Kyle Baley

unread,
Feb 12, 2010, 2:46:22 PM2/12/10
to GWT Dispatch
I was able to work my way through these steps and get authentication
checking working, I think. I didn't actually create my own
SecureDispatchAsync or SecureDispatchService classes. Just assumed
those would be used by default if I registered my
SecureDispatchModule. Anyway, if I'm following correctly, any action
you execute should throw an InvalidSessionException if the user isn't
logged in, yesno?

Assuming that's correct, what is the next step if you want to use this
to get users to log in? Should I use the ExceptionHandler to check for
InvalidSessionException and redirect to the login page from there? Or
create my own SecureDispatchAsync class that redirects?

Another question: what is a good way to secure only some actions? The
obvious one is the login, which I don't want to secure. I saw mention
on TurboManage that a @Secure annotation might be a good idea.

Also, let me know if I'm not using correct terminology. I'm a
seasoned .NET developer cutting his teeth on Java in general.

David Peterson

unread,
Feb 14, 2010, 9:02:53 PM2/14/10
to gwt-di...@googlegroups.com
The SecureDispatchXXX classes don't actually require that a user is authenticated, and they don't do any authentication themselves. All they do is ensure that the user's token is sent to the server in a secure way. It's up to you to provide classes on both ends that a) provide the token (client side) and b) confirm the token is valid (server side). That token can equally be 'null', which would be for anonymous users. As such, I use the SecureDispatch for all actions, and simply assume that 'null' tokens are for anonymous users. There is then an extra check to determine if an Action is actually executable by an anonymous user.

Hope that helps.

David

Kyle Baley

unread,
Feb 15, 2010, 6:14:31 PM2/15/10
to GWT Dispatch
Okay, that makes sense. Where does the check for anonymous actions
occur? I thought my implementation of SecureSessionValidator would be
the logical place but I can't see how to determine which action is
being executed.

Kyle Baley

unread,
Feb 15, 2010, 10:39:05 PM2/15/10
to GWT Dispatch
I came up with something that works but it doesn't feel right. I
created my own SecureDispatchService implementation inheriting from
AbstractSecureDispatchServlet. It's essentially a duplicate of
GuiceSecureDispatchServlet but with the execute method overridden like
so:


@Override
public Result execute(String sessionId, Action<?> action) throws
ActionException,
ServiceException {

if ( anonymousActions.contains(action) ) {
return getDispatch( ).execute( action );
}

return super.execute(sessionId, action);
}

Where anonymousActions is a registry of actions that don't require
authentication.

This feels very much like I'm working around the framework instead of
with it though.

Reply all
Reply to author
Forward
0 new messages