Implementing login and maintaining sessions

72 views
Skip to first unread message

Rodrigo

unread,
Jun 21, 2010, 5:17:00 PM6/21/10
to Google Web Toolkit
Hi,

Can someone point me in the right direction to implement a login +
session system? What are the best practices? I read this page:

http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ

but am still confused about how HttpSessions are to be used, how to
generate session ids, check if they're valid, etc. Any help is greatly
appreciated!

-Rodrigo

Jaroslav Záruba

unread,
Jun 21, 2010, 5:26:31 PM6/21/10
to google-we...@googlegroups.com
You don't need to generate session ids, they are generated automatically by server. You can invalidate session though, as you may notice in HttpSession API. This results in new session being generated. (I'm not sure though whether this happens immediately or on following http request. But that can be tested easily.)


--
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.


Bruno Lopes

unread,
Jun 21, 2010, 6:58:06 PM6/21/10
to google-we...@googlegroups.com
HI, maybe this peace of code can Help  :) :

You can use two modules/entries, one for the login other after login

on login

Client side:

public void onModuleLoad() {
        this.setLoginPanel();
        LogUtils.info("Showing Login page");
    loginButton = new Button("Login");
        loginButton.addListener(new ButtonListenerAdapter() {
            public void onClick(Button button, EventObject e) {
                userAuthentication();
            }
        });
   
      .....


private void userAuthentication() {
        if (this.userNameField.getValueAsString().equals(""))
            Window.alert("username must not be empty.");
        else {
            loginService = GWT.create(LoginService.class);
            String username = this.userNameField.getValueAsString();
            String password = this.passwordField.getValueAsString();
            this.loginService.login(username, password,
                    new AsyncCallback<LoginResponse>() {
                public void onFailure(Throwable caught) {
                    Window.alert("server side failure: " + caught);
                }
                public void onSuccess(LoginResponse result) {
                    if (result.isLoginSuccess()){
                        Window.Location.replace("./../Main.html?gwt.codesvr=127.0.0.1:9997");
                    }
                    else Window.alert("username or password invalid.");
                }
            });
        }
    }   


ON SERVER SIDE (the login method):

public LoginResponse login(String username, String password) {
        LoginPService loginService = ServiceLocator.getLoginService();
        Person person = null;
       
        try {
            ManageLogs.info("Try to login for user: "+username);
            person = loginService.getUserByUsername(username);
       
        if (person == null){
            return new LoginResponse(false, false);
        } else if (!loginService.checkPassword(password)){
            return new LoginResponse(false, false);
        }
       
        } catch (Throwable e) {
           
            return new LoginResponse(false, false);
        }
       
        ManageLogs.info("Login sucessful for user: "+username);
       
        LoginResponse response = new LoginResponse();
        response.setLoginSuccess(true);
       
        /*Creates de session*/
        MainSession padroesSession = mainSession.getInstance();
        mainSession.setRequest(getThreadLocalRequest());
       
       
       mainSession.setUser(person);
        return response;
    }

THE MainSession

private static MainSession  mainSession=null;

    public static MainSession getInstance(){
        if(mainSession == null){
            mainSession = new MainSession();
            return mainSession;
        } else {
            return mainSession;
        }
    }

    private MainSession(){

    }

    private static final String USER_SESSION = "userSession";
    private HttpServletRequest request = null;
    private HttpSession session = null;
    private String sessionId = "";
   

    public Person getUser(){

        if(null == session) return null;

        return session.getAttribute(USER_SESSION) != null ?
                (Person)session.getAttribute(USER_SESSION) : null;

    }

    public HttpSession getSession(){
        return session;
    }
   
    public void invalidate(){
        if(request!=null)
            if(request.getSession(false)!= null)
                 request.getSession(false).invalidate();
        if(null != session){   
            session.invalidate();
            session = null;
        }
        setSessionId(null);
       
    }

    public void setUser(Person user){
        if(null == user){
            if(session!=null) session.removeAttribute(USER_SESSION);
            return;
        }
       
        if(null != request)
            this.session = request.getSession(true);
       
        if(session!=null){
            session.setAttribute(USER_SESSION, user);
            setSessionId(session.getId());
        }
       
    }

    public String getId(){
        return request.getSession(false).getId();
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    public String getSessionId() {
        return sessionId;
    }

    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }

....

ON THE SECOND ENTRY

public void onModuleLoad() {
        LogUtils.info("Loading Padroes Module");
        MainSessionServiceAsync mainSessionService = GWT.create(MainSessionService.class);
   
       
        AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>(){
            @Override
            public void onFailure(Throwable caught) {
                LogUtils.debug("no session available");
                Window.Location.replace("./../Login.html");
            }

            @Override
            public void onSuccess(Boolean result) {
                if(!result){
                    LogUtils.debug("no session available");
                    Window.Location.replace("./../Login.html");
                    return;
                }
               
                LogUtils.info("creating new Session Time Out for this session");
            /* initialize timers for session time out control */  
             new SessionTimeOutControl();
               
             /* Creates de layout +/
                doLayout();

            }
        };

        try{
           
            mainSessionService.isValidSession(callback);


        }catch(Exception e){
            e.printStackTrace();

        }


public void doLayout(){
        AsyncCallback<PageConfiguration[]> callback = new AsyncCallback<PageConfiguration[]>(){
            @Override
            public void onFailure(Throwable caught) {
                LogUtils.debug("server side error on getting PageConfiguration");
                Window.Location.replace("./../Login.html");
            }

            @Override
            public void onSuccess(PageConfiguration[] result) {
                mainPanel.setStyleName("panel-border");
                mainPanel.setFrame(true);
                .......


Hope it helps :)


2010/6/21 Jaroslav Záruba <jarosla...@gmail.com>

Rodrigo

unread,
Jun 22, 2010, 9:16:38 AM6/22/10
to Google Web Toolkit
Thanks for the response... A few questions come up:

1. I'm using an HttpServlet for authentication, along with
RemoteServiceServlets for GWT-RPCs. But if I create an HttpSession in
my authentication servlet, I cannot seem to access it on the
RemoteServiceServlet... How am I supposed to access it? Example:

// In authentication HttpServlet
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// ...
req.getSession().setAttribute("user", new User("testUser")); //
creates a session if it didn't exist beforehand
// ...
}

// In GWT RPC servlet
public List<Offer> getOffers(int productId) {
// ...
User user = (User)
getThreadLocalRequest().getSession().getAttribute("user"); // returns
null
// ...
}


2. Why are you using a MainSession singleton object? I don't see it...
Wouldn't it also fail once you have multiple users logged in at the
same time?

3. In your Main page, you're doing 2 sequential RPC calls before you
render anything: one to check logged in status, and one to load page
contents. Is this advisable or could it be avoided somehow? For
example, the server could set up a cookie with 'loggedIn=true' so that
you can skip the first RPC at least. And whenever you actually have to
fetch private content, the server can fail with a
AuthenticationException if the user is in fact not logged in. So if a
malicious user fakes the cookie to say he's logged in, the most he'll
ever see is a 'Logout' button when there shouldn't be one. Any other
place that needs to show user-specific information would still be
protected at the server. Does this make sense? What are the drawbacks
of this?

4. I assume the SessionTimeoutControl() object just sends an RPC to
the server every x seconds to check if the session is still alive or
not, correct? How do HttpSessions work across tabs and browsers? If my
user has 2 tabs open at my site, does he have 1 or 2 sessions? If it's
2 browsers?

Thanks!

On Jun 21, 6:58 pm, Bruno Lopes <bruno.lourenco.lo...@gmail.com>
wrote:
> 2010/6/21 Jaroslav Záruba <jaroslav.zar...@gmail.com>
>
> > You don't need to generate session ids, they are generated automatically by
> > server. You can invalidate session though, as you may notice in HttpSession
> > API. This results in new session being generated. (I'm not sure though
> > whether this happens immediately or on following http request. But that can
> > be tested easily.)
>
> > On Mon, Jun 21, 2010 at 11:17 PM, Rodrigo <ipi...@gmail.com> wrote:
>
> >> Hi,
>
> >> Can someone point me in the right direction to implement a login +
> >> session system? What are the best practices? I read this page:
>
> >>http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecur...
>
> >> but am still confused about how HttpSessions are to be used, how to
> >> generate session ids, check if they're valid, etc. Any help is greatly
> >> appreciated!
>
> >> -Rodrigo
>
> >> --
> >> 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<google-web-toolkit%2Bunsu...@googlegroups.com>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/google-web-toolkit?hl=en.
>
> >  --
> > 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<google-web-toolkit%2Bunsu...@googlegroups.com>
> > .

Rodrigo

unread,
Jun 22, 2010, 9:33:31 AM6/22/10
to Google Web Toolkit
Ok I just answered 1.5 of my questions:

#1- It actually does work, using getThreadLocalRequest().getSession().
My test had failed for an alternate reason.
#4- (second half) Sessions are per-browser, so multiple tabs in the
same browser share sessions, but cross-browser tabs do not.

The other questions remain...
> ...
>
> read more »

Bruno Lopes

unread,
Jun 22, 2010, 9:54:56 AM6/22/10
to google-we...@googlegroups.com
FYI,

On Tue, Jun 22, 2010 at 2:16 PM, Rodrigo <ipi...@gmail.com> wrote:
Thanks for the response... A few questions come up:

1. I'm using an HttpServlet for authentication, along with
RemoteServiceServlets for GWT-RPCs. But if I create an HttpSession in
my authentication servlet, I cannot seem to access it on the
RemoteServiceServlet... How am I supposed to access it? Example:

// In authentication HttpServlet
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
     // ...
     req.getSession().setAttribute("user", new User("testUser")); //
creates a session if it didn't exist beforehand
     // ...
}

// In GWT RPC servlet
public List<Offer> getOffers(int productId) {
     // ...
     User user  = (User)
getThreadLocalRequest().getSession().getAttribute("user"); // returns
null
     // ...
}


2. Why are you using a MainSession singleton object? I don't see it...
Wouldn't it also fail once you have multiple users logged in at the
same time?

It works fine for multiple users  because for each new request a new different session ID will be
generated, and so a new session.

3. In your Main page, you're doing 2 sequential RPC calls before you
render anything: one to check logged in status, and one to load page
contents. Is this advisable or could it be avoided somehow? For
example, the server could set up a cookie with 'loggedIn=true' so that
you can skip the first RPC at least. And whenever you actually have to
fetch private content, the server can fail with a
AuthenticationException if the user is in fact not logged in. So if a
malicious user fakes the cookie to say he's logged in, the most he'll
ever see is a 'Logout' button when there shouldn't be one. Any other
place that needs to show user-specific information would still be
protected at the server. Does this make sense? What are the drawbacks
of this?

I need those 2 because I can olny load the content if the authentication was successful,
and when that happens on the server side, the http session is created and also the user
information is loaded.
An only after this is possible to load the content.

With a cookie, then on the client side I need to access to that cookie... actually I didn't check that,
but the access to the cookie is not done on the server side, also ?
 
4. I assume the SessionTimeoutControl() object just sends an RPC to
the server every x seconds to check if the session is still alive or
not, correct? How do HttpSessions work across tabs and browsers? If my
user has 2 tabs open at my site, does he have 1 or 2 sessions? If it's
2 browsers?

The session time out control actual do more than that it uses the gwt Timer to  initialize an schedule in a new thread
for a defined period of time, and the alert the user when the session is about to expire,
if there the user do any event it will send a keep alive and  re-initialize the schedule, otherwise invalidate session
e redirects to Login page.

Across tabs will keep the same session until the user logout or the session time out happens.
Across browsers a new session is nedded.

Hope it helps :)

Bruno
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.

Bruno Lopes

unread,
Jun 22, 2010, 9:57:27 AM6/22/10
to google-we...@googlegroups.com
FYI,


On Tue, Jun 22, 2010 at 2:33 PM, Rodrigo <ipi...@gmail.com> wrote:
Ok I just answered 1.5 of my questions:

#1- It actually does work, using getThreadLocalRequest().getSession().
My test had failed for an alternate reason.

great! it works with me too :)
 
#4- (second half) Sessions are per-browser, so multiple tabs in the
same browser share sessions, but cross-browser tabs do not.

That's true
 
The other questions remain...

see my  other answer
 
--
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.

Rodrigo

unread,
Jun 22, 2010, 10:07:05 AM6/22/10
to Google Web Toolkit
Not sure if I understood your question.. But yes, the cookie is
accessed both at the client and at the server. So the server would set
it to 'loggedIn=true' upon a successful login, and clear it whenever
the user logs out OR if the server gets a request for private
information but the Session indicates that the user is not logged in..
In that case, it clears the cookie and fails with an
AuthenticationException. The client redirects the user to login
whenever an AuthenticationException is received.

Thus, the usage of the cookie allows the client to save some RPC calls
to the server. If a page doesn't contain private user-specific
content, but should still look different based on whether the user is
logged in or not, then the client can go off the cookie's information
and decide whether to display a 'Login' or 'Logout' button, for
example.

On Jun 22, 9:54 am, Bruno Lopes <bruno.lourenco.lo...@gmail.com>
wrote:
> ...
>
> read more »

Bruno Lopes

unread,
Jun 22, 2010, 11:38:22 AM6/22/10
to google-we...@googlegroups.com
Hey,
I try your approach with cookies and seems to works fine!

Thanks :)


--

Bruno Lopes

unread,
Jun 22, 2010, 3:37:25 PM6/22/10
to google-we...@googlegroups.com
You are right about multiple session's,

I have to implements an store to keep the sessions ID
in order to be able to have multiple users logged in without losing their sessions :)
Reply all
Reply to author
Forward
0 new messages