Callout for remember me?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Callout for remember me?

Jon Chase
First off, I understand that the view of the Shiro developers is that remember me is not typically a good idea from a security standpoint.

That said, I'm using the remember me functionality. :)

Upon successful login (not remember me), my app stores some data in the HttpSession.  This data is required later for app pages to load properly.  

I'd like to have this data stored in the HttpSession upon successful remember me authentication as well, but I can't seem to find a callout to do it with.  I'm not sure if I'm missing it or not, but ideally it would be a method that is called once when the remember me authentication happens.

For the time being I've overridden AbstractRememberMeManager.getRememberedPrincipals() with something like this (pseudo):

public PrincipalCollection getRememberedPrincipals() {
        PrincipalCollection ps = super.getRememberedPrincipals();
        HttpServletRequest req = (HttpServletRequest) WebUtils.getRequiredServletRequest();
        req.getSession().setAttribute("foo", 42);
        req.getSession().setAttribute("bar", "baz");
        return ps;
}

It looks like the above method gets called every time a secured resource is requested, which is not desirable in my use case.

FYI, I'm using the Grails Shiro plugin.

Thanks for any ideas/suggestions. :)

Jon
Reply | Threaded
Open this post in threaded view
|

Re: Callout for remember me?

Les Hazlewood-2
On Mon, Feb 22, 2010 at 12:17 AM, Jon Chase <[hidden email]> wrote:
>
> First off, I understand that the view of the Shiro developers is that
> remember me is not typically a good idea from a security standpoint.
>
> That said, I'm using the remember me functionality. :)

Actually, its not bad to use RememberMe - it is a nice feature.  But
RememberMe does not represent an *authenticated* user, so we need to
make that distinction so Shiro users can make decisions accordingly.

> Upon successful login (not remember me), my app stores some data in the
> HttpSession.  This data is required later for app pages to load properly.

Shiro stores an encrypted version of the PrincipalCollection in the
remember me cookie.  Can you store that data as principals in the
collection?  If so, that data will be automatically saved and
available when the identity is retrieved.  Then you could retrieve it
later from subject.getPrincipals();  This is why there can be multiple
principals other than just the application's unique identifier.

But you're right, this process occurs on every request until the user
is properly authenticated and so it might not be the most efficient
mechanism - it might be good to provide a callback or event to react
to this.  Could you please open a Jira feature request if you'd like
this?

In the meantime, the best place for logic like this is probably the
SubjectFactory implementation - you're basically editing Subject state
based on when the instance is created.  You'll probably want to
subclass DefaultSubjectFactory or DefaultWebSubjectFactory depending
on your environment.

Let us know if this is ok or if you have other ideas that might better
reflect your environment - we're certainly open.

Regards,

Les
Reply | Threaded
Open this post in threaded view
|

Re: Callout for remember me?

arecibo
I have the same requirements. I am trying to use a custom security manager that extends from DefaultSecurityManager and a custom rememberMe manager that extends from CookieRememberMeManager. In my custom class, I override onSuccessfulLogin and rememberMeSuccessfulLogin to provide my own after-login hook:

  @Override
  void onSuccessfulLogin(AuthenticationToken token, AuthenticationInfo info, Subject subject) {
    super.onSuccessfulLogin(token, info, subject)
    afterLogin(token, info, subject)
  }

  @Override
  void rememberMeSuccessfulLogin(AuthenticationToken token, AuthenticationInfo info, Subject subject) {
    super.rememberMeSuccessfulLogin(token, info, subject)
    afterLogin(token, info, subject)
  }

It works fine when users login with username and password. But when users login with remember Me, these methods are not called. Is this the right way to add a hook for remember me login?

Thanks,
Kenny
Reply | Threaded
Open this post in threaded view
|

Re: Callout for remember me?

BowlingX
This post has NOT been accepted by the mailing list yet.
I know it's an old question, but it was never answered...
Is there any hook that provides a way to detect session recreation with a rememberMe Cookie?

"onSuccessfulLogin" is not called (only after a regular login)

David
dan
Reply | Threaded
Open this post in threaded view
|

Re: Callout for remember me?

dan
Hi --

I am also encountering the same problem.

In my case, whenever a remember me logon occurs, I wish to invoke some code, let's say foo(subject), which is passed the Subject.  What I think I really want is that a onSuccessfulRememberMeLogin() method be part of the CookieRememberMeManger class, and that it would be called when a remember me cookie is authenticated and would be called only once.  (I know that there is a onSuccessfulLogon() method but it is called whenever any logon is successful.)

(When a regular login is successful, I call onSuccessfulLogin() in my FormAuthenticationFilter-extended class which then invokes my app-specific code, foo(subject) to do some setup.)

I can't hook into getRememberedPrincipals() because the Subject hasn't been created at this point.  I thought that perhaps in SecurityManager, I could hook into createSubject() but this method might be called from other places.  

Any ideas?

Thanks much in advance,
Dan
dan
Reply | Threaded
Open this post in threaded view
|

Re: Callout for remember me?

dan
Hi --

Just a follow-up.  I was able to resolve this issue by extending DefaultWebSecurityManager and overriding createSubject(SubjectContext subjectContext).  It now has almost the same functionality but allows a callout to a new method to handle my application-specific initialization for remember me sessions.

The key change in createSubject() were these lines:

                final boolean before = context.getPrincipals() == null;
                context = resolvePrincipals(context);

                Subject subject = doCreateSubject(context);

                if (before && context.getPrincipals() != null)
                {
                        Object o = context.getPrincipals().getPrimaryPrincipal();
                        if (o instanceof String)
                        {
                                onSuccessfulRememberMeLogin(subject, (String) o);
                        }
                }

The new method is:

        private void onSuccessfulRememberMeLogin(Subject subject, String username)

Hope this helps,
Dan