Open GoogleCodeExporter opened 9 years ago
gwt-sl library has helper class ServletUtils which allows you to access HTTP
request & response correctly. But you have to use it (gwt-sl) to access your
dispatcher service. It is an integration library for Spring + GWT + other stuff.
Original comment by ladislav...@gmail.com
on 7 Jul 2010 at 10:21
I believe this issue would solve the following dilemma that I am facing:
Background info: We are using the GuiceSecureDispatchService and simple J2EE
analog of the AppEngineSecureSessionValidator.
Here is the high level flow we envision:
1) User enters username and password and clicks Login
2) The action is handled on the server by a LoginActionHandler which looks up
the username from our authentication service and validates the password.
3) If the password is a match we would like to store, on the server, a
representation of the application specific UserSession and associate it with
the JSESSIONID cookie provided to the browser upon first request.
4) When a secure resource is subsquently requested we can follow the model
provided by the AppEngineSecureSessionValidator but instead of using the
UserServiceFactory, which is GAE specific, we would look up the valid
UserSession by using the JSESSIONID cookie.
I am pretty sure that we must rely on the JSESSIONID cookie in order provide
the single sign on behavior we need.
Without the ability to access the Session (and potentially the
HTTPServletRequest) in the LoginActionHandler it doesn't seem possible to
implement this workflow or single sign on behavior in general. Am I mistaken,
is there some other way to access the JSESSIONID inside an ActionHandler as a
part of gwt-dispatch? As a side note Spring integration is not an option for
our team at the moment and it would be overkill to bring in the whole gwt-sl
library just to get access to the JSESSIONID.
Original comment by adamben...@gmail.com
on 26 Oct 2010 at 10:39
In response to my previous comment, it would be very convenient to have access
to the HttpServletRequest because there will almost certainly be information in
the cookies that would be useful to the action handler.
And thanks in advance for any time spent to consider this issue.
Original comment by adamben...@gmail.com
on 26 Oct 2010 at 11:01
Binding your handlers with guice gives you access to the session, request and
response objects via providers. They get automatically injected into the
handler if your constructor looks something like this:
@Inject public StoreFooHandler(Logger logger, Provider<HttpSession>
sessionProvider, Provider<HttpServletRequest> requestProvider,
Provider<HttpServletResponse> responseProvider, PMF pmf){
...
}
e.g. if you want to access something in the session this looks like:
this.sessionProvider.get().getAttribute("FooSessionParameter");
Hope this helps.
Original comment by pfiste...@gmail.com
on 27 Oct 2010 at 8:48
That did the trick, thank you!
Original comment by adamben...@gmail.com
on 27 Oct 2010 at 7:37
I've been using that Guice trick you mentioned to get the session, request and
response, but I've been reading up on cold boot times on appengine and it seems
that getting rid of Guice helps improve load times by a lot.
http://turbomanage.wordpress.com/2010/03/26/appengine-cold-starts-considered/
It would be nice to get access to them via the execute method of the
dispatcher. Couldn't this be done by passing them along in the execute method?
Original comment by ssaam...@gmail.com
on 28 Oct 2010 at 4:42
"It would be nice to get access to them via the execute method of the
dispatcher. Couldn't this be done by passing them along in the execute method?"
The issue was addressed here:
http://code.google.com/p/gwt-dispatch/issues/detail?id=4
Original comment by butani.a...@gmail.com
on 1 Nov 2010 at 10:02
Hi,
I am not using Guice but Spring with GWT and am fairly new to this.
Can someone please elaborate how to get session objects in ActionHandlers?
I want to make a LoginActionHandler which checks user login credentials and
then adds user details to session object.
Original comment by inet2...@gmail.com
on 25 Mar 2011 at 10:39
I would be interested in that too...
Original comment by michaelm...@gmail.com
on 29 Mar 2011 at 2:59
Re: Spring instead of Guice
We are currently running a project that uses Spring as the main DI engine on
the Server and have found that to make use of GWT-Dispatch you have to use
Guice as they are intimately tied together. One possibility is to create a
series of bridge bindings that bind Guice to Spring using an approach similar
to Guice's SpringIntegration class. Essentially you are telling Guice to
lookup any dependencies in the ApplicationContext so Spring is really doing the
injection and because Guice doesnt care how it gets the instance this seems to
work well. Unfortunately, we have not found a way around Guice entirely, but
this bridge approach does the trick.
To answer the question about session injection, we didnt find a good way to get
the session injected directly because that would require that Guice builds your
handlers, which if you follow the advice above doesnt happen - Spring is doing
all the object construction. You can however access anything Spring knows about
and manage injection like you normally would with Spring. In our case we
created and inected a UserProvider that was aware of the SecurityContext and
ApplicationContext so it could access almost anything it wanted including the
httpsession. Via the API exposed by the UserProvider we were able to provide
access to any handler.
As an architectural aside, I would recommend against putting your
authentication/login into the GWT app, especially if you see a need for Spring
Security down the road. You will be tied to the command pattern or rpc approach
which isnt necessarily easy to connect to Spring's authentication mechanisms.
We have had much more success moving the login to a separate JSP page and
treating the GWT app itself as a 'trusted zone' so you dont have to deal with
asynchronous services starting up and being dependent on being authenticated.
It made for much less code and a much cleaner isolation of trusted/untrusted
areas of the application.
In our app we have the following action mapping module
/**
* Module which binds the actions and corresponding handlers
*/
public class ActionMappingModule extends HandlerModule
{
private final ApplicationContext applicationContext;
public ActionMappingModule(ApplicationContext applicationContext)
{
this.applicationContext = checkNotNull(applicationContext);
}
@Override
protected void configureHandlers()
{
GuiceToSpringBinder guiceToSpringBinder = new GuiceToSpringBinder(applicationContext, binder());
guiceToSpringBinder.bindGuiceToSpring();
bindHandler(LoadUsersAction.class, LoadUsersActionHandler.class);
bindHandler(GetUserByIdAction.class, GetUserByIdActionHandler.class);
}
}
And the GuiceToSpringBinder looks like:
public class GuiceToSpringBinder
{
private final ApplicationContext applicationContext;
private final Binder binder;
public GuiceToSpringBinder(final ApplicationContext applicationContext, final Binder binder)
{
this.binder = checkNotNull(binder);
this.applicationContext = checkNotNull(applicationContext);
}
public void bindGuiceToSpring()
{
binder.bind(BeanFactory.class).toInstance(applicationContext);
binder.bind(LoadUsersActionHandler.class).toProvider(SpringToGuiceInjector.fromSpring(LoadUsersActionHandler.class,
"loadUsersActionHandler"));
binder.bind(GetUserByIdActionHandler.class).toProvider(SpringToGuiceInjector.fromSpring(GetUserByIdActionHandler.class,
"getUserByIdActionHandler"));
}
}
And SpringToGuiceInjector looks like this (note that this is a slight
modification on the SpringSupport class included in Guice:
public class SpringToGuiceInjector
{
private SpringToGuiceInjector()
{
}
/**
* Creates a provider which looks up objects from Spring using the given name.
* Expects a binding to {@link org.springframework.beans.factory.BeanFactory}. Example usage:
*
* <pre>
* bind(DataSource.class).toProvider(fromSpring(DataSource.class, "dataSource"));
* </pre>
*/
public static <T> Provider<T> fromSpring(Class<T> type, String name)
{
return new InjectableSpringProvider<T>(type, name);
}
/**
* Binds all Spring beans from the given factory by name. For a Spring bean
* named "foo", this method creates a binding to the bean's type and {@code @Named("foo")}.
*
* @see com.google.inject.name.Named
* @see com.google.inject.name.Names#named(String)
*/
public static void bindAll(Binder binder, ListableBeanFactory beanFactory)
{
binder = binder.skipSources(SpringIntegration.class);
for (String name : beanFactory.getBeanDefinitionNames())
{
Class< ? > type = beanFactory.getType(name);
bindBean(binder, beanFactory, name, type);
}
}
static <T> void bindBean(Binder binder, ListableBeanFactory beanFactory, String name, Class<T> type)
{
SpringProvider<T> provider = SpringProvider.newInstance(type, name);
try
{
provider.initialize(beanFactory);
}
catch (Exception e)
{
binder.addError(e);
return;
}
binder.bind(type).annotatedWith(Names.named(name)).toProvider(provider);
}
static class SpringProvider<T> implements Provider<T>
{
BeanFactory beanFactory;
boolean singleton;
final Class<T> type;
final String name;
public SpringProvider(Class<T> type, String name)
{
this.type = checkNotNull(type, "type");
this.name = checkNotNull(name, "name");
}
static <T> SpringProvider<T> newInstance(Class<T> type, String name)
{
return new SpringProvider<T>(type, name);
}
void initialize(BeanFactory beanFactory)
{
this.beanFactory = beanFactory;
if (!beanFactory.isTypeMatch(name, type))
{
throw new ClassCastException("Spring bean named '" + name + "' does not implement " + type.getName() + ".");
}
singleton = beanFactory.isSingleton(name);
}
@SuppressWarnings("unchecked")
@Override
public T get()
{
return (T)(singleton ? getSingleton() : beanFactory.getBean(name));
}
volatile T instance;
@SuppressWarnings("unchecked")
private T getSingleton()
{
return (T)beanFactory.getBean(name);
}
}
static class InjectableSpringProvider<T> extends SpringProvider<T>
{
InjectableSpringProvider(Class<T> type, String name)
{
super(type, name);
}
@Inject
@Override
void initialize(BeanFactory beanFactory)
{
super.initialize(beanFactory);
}
}
}
Original comment by adamben...@gmail.com
on 29 Mar 2011 at 4:43
Original issue reported on code.google.com by
steve.ar...@gmail.com
on 10 Jun 2010 at 8:12