Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use @SessionScoped with Guice

Hi
I am currently playing with Guice and @SessionScoped. To give it more sense, I decided to build a (very simple) authentication process.

Below, I will explain each step I have done. Then I will ask you some questions.

[1] I have create an Identity class which represents a person (guest or user) :

@SessionScoped
public class Identity implements Serializable
{
    private String uid;
    private String name;

    public boolean isAuthenticate()
    {
        return uid != null;
    }

    public void logout()
    {
        this.uid = null;
    }

    /*Setters-Getters*/
}

[2] Next, I created an Authentication class that log-in user:

public class Authentication
{
    @Override
    public Identity authenticate(String login, String password)
    {
        /*some code*/

        Identity identity = new Identity();
        identity.setUid(user.getId());
        return identity;
    }
}

[3] Then, in my Servlet, I log-in the user :

@RequestScoped
public class LoginAction
{
    @Inject
    Injector injector;

    protected void login(HttpServletRequest req, HttpServletResponse resp)
    {
            Identity identity = injector.getInstance(Identity.class);
            Authentication auth = new Authentication();
            identity = auth.authenticate("login","password");
    }
}

[4] Finally, I create a Filter that show me if user is authenticated :

@Singleton
public class SecurityFilter implements Filter
{
    @Inject
    private Injector injector;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)
    {
        Identity identity = injector.getInstance(Identity.class);

        if(identity.isAuthenticate())
        {
            System.err.println("USER");
        }
        else
        {
            System.err.println("GUEST");
        }

        chain.doFilter(request, response);
    }
}

Well, this code is not working. My Identity's uid is always "null".

Let's go for questions :

a - First of all, Why did my code not works ?
b - Is @SessionScoped equivalent to set the object in HttpSession ?
c - How to invalidate the Identity object (only it) in (http)session ?
d - Generally, In which case did we have to use @SessionScoped?

Thanks you for reading,
Waiting your answers.

like image 899
Pierre Avatar asked Apr 25 '11 09:04

Pierre


1 Answers

[a] You're assigning a new instance of Identity to a local variable in LoginAction, not replacing the instance managed by Guice. You could solve the problem by populating the uid and name fields on the existing Identity instance managed by Guice.

For example, instead of

identity = auth.authenticate("login","password"); 

you could say:

Identity identity = injector.getInstance(Identity.class);
Authentication auth = new Authentication();
Identity authenticated = auth.authenticate("login","password");
identity.setUid(authenticated.getUid());
identity.setName(authenticated.getName());

There are cleaner ways to do it, but you get the idea.

[b]/[d] That's correct: @SessionScoped is equivalent to setting a variable in the HttpSession, and this is the kind of situation that you would use it. You'll need it for objects that need to be unique across sessions, but need to be available for every request.

[c] I'm not quite sure what you mean, but if you're wanting to redirect to different places in the app depending on whether the user is logged in, your filter design is a common way to do that.

Some improvements that you could make:

  • Have a SessionScoped service that manages the session's user's Identity, and make sure it's synchronized on the Identity instance. That way you won't have concurrency troubles if a user makes two requests in quick succession.
  • Prefer injecting Providers instead of injecting the Injector(examples here) to decouple your classes from Guice.
  • Inject dependencies into your classes' constructors, instead of injecting fields. This allows for easier testing (by providing mock/stub dependencies in tests).
like image 57
Daniel Avatar answered Sep 18 '22 04:09

Daniel