You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Tauren Mills <ta...@groovee.com> on 2011/02/21 07:46:13 UTC

Create Subject and Login in same request

I'm attempting to create a new member and immediately log the user in within
the same request, but I'm getting an UnknownAccountException:
    Realm was unable to find account data for the submitted
AuthenticationToken

What's the best way to go about doing this? I've got code that looks like
this:

  // Create new member
  member = memberService.createMember(member);

  // Login new member
  UsernamePasswordToken token =
    new UsernamePasswordToken(dto.getUsername(), dto.getPassword(), true);
  SecurityUtils.getSubject().login(token);  // Exception thrown

Perhaps there's a better way to accomplish what I need to do. Here's my
objective:

1. User fills in simple signup form (username, password, email) and submits
it.
2. New account is created, and activation email is sent to user
3. Profile form is immediately shown to user (even before they activate),
user enters first name, last name, birthdate, etc.
4. User is shown a list of projects they can join, selects some, and joins
them.

Steps 3 and 4 don't have to be done now. The user can do them the next time
they use the system after logging in. But I want to encourage them to take
care of it right now, while not having lots of required fields in the signup
form.

At this point, the user must authenticate their account before they can
actually use the system. My goal is to allow the user to enter everything
without interruption, such as having to click an activation link in email,
or having to login after creating an account. But to update the profile and
add projects, I need the user to be logged in.

Any suggestions?

Thanks,
Tauren

Re: Create Subject and Login in same request

Posted by Tauren Mills <ta...@groovee.com>.
Les,

Thanks for the help. Sorry, I meant to respond to this sooner, but it
slipped my mind. I realized shortly after sending this message that my code
was inside of a method in a Spring and Hibernate annotated class as such:

@Transactional
@Service

So I'm assuming the member hadn't been persisted yet, which is why Shiro
couldn't locate it. All my database access is via DAO objects that are used
in my service layer. So I'm going to have figure out the best way to flush
hibernate, or change the way transactions work for this situation, or
something.

Thanks,
Tauren


On Mon, Feb 21, 2011 at 8:36 PM, Les Hazlewood <lh...@apache.org>wrote:

> On Sun, Feb 20, 2011 at 10:46 PM, Tauren Mills <ta...@groovee.com> wrote:
> > I'm attempting to create a new member and immediately log the user in
> within
> > the same request, but I'm getting an UnknownAccountException:
> >     Realm was unable to find account data for the submitted
> > AuthenticationToken
> > What's the best way to go about doing this? I've got code that looks like
> > this:
> >   // Create new member
> >   member = memberService.createMember(member);
> >
> >   // Login new member
> >   UsernamePasswordToken token =
> >     new UsernamePasswordToken(dto.getUsername(), dto.getPassword(),
> true);
> >   SecurityUtils.getSubject().login(token);  // Exception thrown
> > Perhaps there's a better way to accomplish what I need to do. Here's my
> > objective:
> > 1. User fills in simple signup form (username, password, email) and
> submits
> > it.
> > 2. New account is created, and activation email is sent to user
> > 3. Profile form is immediately shown to user (even before they activate),
> > user enters first name, last name, birthdate, etc.
> > 4. User is shown a list of projects they can join, selects some, and
> joins
> > them.
> > Steps 3 and 4 don't have to be done now. The user can do them the next
> time
> > they use the system after logging in. But I want to encourage them to
> take
> > care of it right now, while not having lots of required fields in the
> signup
> > form.
> > At this point, the user must authenticate their account before they can
> > actually use the system. My goal is to allow the user to enter everything
> > without interruption, such as having to click an activation link in
> email,
> > or having to login after creating an account. But to update the profile
> and
> > add projects, I need the user to be logged in.
> > Any suggestions?
> > Thanks,
> > Tauren
> >
> >
>
> Hi Tauren,
>
> I'm not sure why this is happening - there is no reason why your code
> can't work the way it is written.  It sounds like a transactional
> issue to me.  Are you using Hibernate?  Hibernate will typically flush
> the session before performing a query, so the data would be propagated
> to the data store before executing the authentication query.  In odd
> cases, you might have to 'flush' the session (although this should not
> be needed).
>
> If not using hibernate, I would ensure that the data is flushed to the
> datastore before performing the query.  I suspect that is why the
> authentication query can't 'see' the user data it needs to look up.
>
> If you can't get around the transactional/flush issues, one potential
> solution is to store their entered username/password into their
> session.  Then have an AuthenticatingFilter that sits in front of the
> URLs that you want immediate access to.  If that filter sees the
> username/password in the session, and they're not considered logged in
> yet, it can log them in automatically before allowing the request
> through.  Not as ideal as figuring out the flush issues IMO, but it
> should work well.
>
> Best,
>
> --
> Les Hazlewood
> Founder, Katasoft, Inc.
> Application Security Products & Professional Apache Shiro Support and
> Training:
> http://www.katasoft.com
>

Re: Create Subject and Login in same request

Posted by Les Hazlewood <lh...@apache.org>.
On Sun, Feb 20, 2011 at 10:46 PM, Tauren Mills <ta...@groovee.com> wrote:
> I'm attempting to create a new member and immediately log the user in within
> the same request, but I'm getting an UnknownAccountException:
>     Realm was unable to find account data for the submitted
> AuthenticationToken
> What's the best way to go about doing this? I've got code that looks like
> this:
>   // Create new member
>   member = memberService.createMember(member);
>
>   // Login new member
>   UsernamePasswordToken token =
>     new UsernamePasswordToken(dto.getUsername(), dto.getPassword(), true);
>   SecurityUtils.getSubject().login(token);  // Exception thrown
> Perhaps there's a better way to accomplish what I need to do. Here's my
> objective:
> 1. User fills in simple signup form (username, password, email) and submits
> it.
> 2. New account is created, and activation email is sent to user
> 3. Profile form is immediately shown to user (even before they activate),
> user enters first name, last name, birthdate, etc.
> 4. User is shown a list of projects they can join, selects some, and joins
> them.
> Steps 3 and 4 don't have to be done now. The user can do them the next time
> they use the system after logging in. But I want to encourage them to take
> care of it right now, while not having lots of required fields in the signup
> form.
> At this point, the user must authenticate their account before they can
> actually use the system. My goal is to allow the user to enter everything
> without interruption, such as having to click an activation link in email,
> or having to login after creating an account. But to update the profile and
> add projects, I need the user to be logged in.
> Any suggestions?
> Thanks,
> Tauren
>
>

Hi Tauren,

I'm not sure why this is happening - there is no reason why your code
can't work the way it is written.  It sounds like a transactional
issue to me.  Are you using Hibernate?  Hibernate will typically flush
the session before performing a query, so the data would be propagated
to the data store before executing the authentication query.  In odd
cases, you might have to 'flush' the session (although this should not
be needed).

If not using hibernate, I would ensure that the data is flushed to the
datastore before performing the query.  I suspect that is why the
authentication query can't 'see' the user data it needs to look up.

If you can't get around the transactional/flush issues, one potential
solution is to store their entered username/password into their
session.  Then have an AuthenticatingFilter that sits in front of the
URLs that you want immediate access to.  If that filter sees the
username/password in the session, and they're not considered logged in
yet, it can log them in automatically before allowing the request
through.  Not as ideal as figuring out the flush issues IMO, but it
should work well.

Best,

-- 
Les Hazlewood
Founder, Katasoft, Inc.
Application Security Products & Professional Apache Shiro Support and Training:
http://www.katasoft.com