shiro-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Animesh Jain" <anim...@itasveer.com>
Subject Re: How to set a custom principal object
Date Mon, 15 Sep 2008 18:18:39 GMT
Hi Les

Here's the realm implementation for doGetAuthenticationInfo()

  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken
token) throws AuthenticationException {
    UsernamePasswordToken upToken = (UsernamePasswordToken) token;
    String username = upToken.getUsername();
    // Null username is invalid
    if (username == null) {
      throw new AccountException("Null usernames are not allowed by this
realm.");
    }

    String password = userSecurityManager.getPasswordForUser(username);
    if (password == null) {
      throw new UnknownAccountException("No account found for user [" +
username + "]");
    }
    return buildAuthenticationInfo(username, password.toCharArray());
  }


On Mon, Sep 15, 2008 at 11:44 PM, Les Hazlewood <lhazlewood@apache.org>wrote:

> In your HibernateRealm, how are AuthenticationInfo objects returned?
> What methods did you override?  This could help me understand the best
> way to tell you how to enable your principal(s) in the
> PrincipalCollection.
>
> On Mon, Sep 15, 2008 at 2:11 PM, Les Hazlewood <les@hazlewood.com> wrote:
> > You don't need to do anything - just include it in your principals
> > collection.  JSecurity will use reflection to call the appropriate
> > getter method to extract the data.
> >
> > For example, if you have a
> >
> > public class UserPrincipals {
> >    getUsername(){...}
> >    getEmail(){...}
> >    getFirstName(){...}
> >    ...
> > }
> >
> > Then this call:
> >
> > <jsec:principal property="username"/>
> >
> > Will do this:
> >
> > Object userPrincipals = subject.getPrincipal();
> > return userPrincipals.getUsername();
> >
> > <jsec:principal property="firstName"/>
> >
> > Does this:
> > Object userPrincipals = subject.getPrincipal();
> > return userPrincipals.getFirstName();
> >
> > etc...
> >
> > No interface to implement or class to extend - it will use reflection
> > to automatically call the getUsername/getFirsName/etc calls...
> >
> > Cheers,
> >
> > Les
> >
> > On Mon, Sep 15, 2008 at 1:40 PM, Animesh Jain <animesh@itasveer.com>
> wrote:
> >> Hi Jeremy
> >>
> >> Thanks. I'll raise my stupid question again.. it really seems I'm
> missing
> >> something elementary here! I'd like to know how do I go about setting a
> >> custom principal object. What interface/class to implement/override.
> >>
> >> Animesh
> >>
> >> On Mon, Sep 15, 2008 at 11:03 PM, Jeremy Haile <jhaile@fastmail.fm>
> wrote:
> >>>
> >>> I prefer that approach as well.  Simply provide a custom principal
> object
> >>> that has several simple properties with the information you want (user
> ID,
> >>> username, etc.)
> >>> The only risk is that any information that is updated during a session
> may
> >>> not be reflected in the principal, so you have to be careful not to use
> >>> stale data.  In my applications, I typically store the user ID in there
> then
> >>> use that to pull the User object from Hibernate.  Since Hibernate
> caches my
> >>> User object in EhCache, this is not a DB hit.
> >>> But if you do have data that doesn't change (such as user ID and
> username)
> >>> returning a principal object with multiple properties works great!
> >>> Jeremy
> >>>
> >>>
> >>> On Sep 15, 2008, at 1:28 PM, Animesh Jain wrote:
> >>>
> >>> Hey Les
> >>>
> >>> Well I'm willing to not use a hibernated object for the principal. I
> think
> >>> it'll be convenient to have access to data like first name, last name,
> >>> email, user id etc in the principal object. The reason I'd prefer a
> >>> principal object rather than a collection of primitive types is that it
> is
> >>> easier to say property="name", than iterating through the principals
> and get
> >>> the n'th element.
> >>>
> >>> But I really did not get where I need to set this principal object or a
> >>> collection of primitive type principals. Which interface/class should I
> >>> implement/extend and how should I tell Jsecurity about it?? The realm
> >>> doesn't seem to have any setPrincipal method to implement.
> >>>
> >>> Thanks a lot for the quick replies Les :)
> >>>
> >>> Animesh
> >>>
> >>> On Mon, Sep 15, 2008 at 10:49 PM, Les Hazlewood <les@hazlewood.com>
> wrote:
> >>>>
> >>>> Ah, the 'property' attribute is for a property of the principal, if
it
> >>>> is not a primitive object.
> >>>>
> >>>> For example, you could have a UserPrincipal class that wraps a
> >>>> username property and an id.  Then you could say <jsec:principal
> >>>> property="username"/>
> >>>>
> >>>> and that would equate to this Java call:
> >>>>
> >>>> subject.getPrincipal().getUsername(); (using reflection of course,
> >>>> because getPrincipal returns an object).
> >>>>
> >>>> But since you're storing primitive values in the PrincipalCollection,
> >>>> there is no need for you to use this attribute in the jsec tag.  It
is
> >>>> much simpler if you do things that way if you can ;)
> >>>>
> >>>> But yes, the Principal can be the User object itself, but this is not
> >>>> recommended.  A PrincipalCollection is often serialized to the client
> >>>> in the form of a cookie and then deserialized later.  If your User
> >>>> objects are 'hibernated', and it appears that yours are, then that
> >>>> User object wouldn't be associated with a Hibernate Session, and if
> >>>> you needed lazy loading, you'd get the infamous
> >>>> LazyInitializationException.  Plus because Hibernate objects are often
> >>>> CGLib proxies, your serialized data (cookie) could be kind of large
-
> >>>> not really desirable.
> >>>>
> >>>> On Mon, Sep 15, 2008 at 1:04 PM, Animesh Jain <animesh@itasveer.com>
> >>>> wrote:
> >>>> > Hi Les
> >>>> >
> >>>> > Yup all that sounds good, but I was wondering what the "property"
> >>>> > attribute
> >>>> > was for in the jsec:principal tag. Isn't there a way to lets say
put
> >>>> > the
> >>>> > user domain object into the principal. Because the documentation
> (and
> >>>> > the
> >>>> > tag implemetation) does seem to imply that this is possible.
> >>>> > jsec:principal
> >>>> > would then by default print principalObject.toString().
> >>>> >
> >>>> > Animesh
> >>>> >
> >>>> > On Mon, Sep 15, 2008 at 10:28 PM, Les Hazlewood <les@hazlewood.com>
> >>>> > wrote:
> >>>> >>
> >>>> >> Hi Animesh,
> >>>> >>
> >>>> >> You can store more than one principal in the PrincipalCollection
> >>>> >> returned by the realm.  Its just the first one in that collection
> is,
> >>>> >> by convention, the 'primary identifier' of your user (e.g.
user id,
> >>>> >> username, etc).  In your case, this sounds like it is the email
> >>>> >> address.  But you could add more to the principal collection.
> >>>> >>
> >>>> >> But that would require you to do this in code:
> >>>> >>
> >>>> >> Iterator i = subject.getPrincipals().iterator();
> >>>> >> i.next(); //skip the primary one.
> >>>> >> String username = (String)i.next();
> >>>> >>
> >>>> >> //print out the username.
> >>>> >>
> >>>> >> Currently the <jsec:principal/> tag does not support
anything like
> >>>> >> <jsec:principal index="1"/>, which would print out the
2nd
> principal
> >>>> >> in the collection, which it sounds like is what you want.
> >>>> >>
> >>>> >> If you want this functionality, please open a Jira issue, and
we'll
> be
> >>>> >> sure to get it in the next release.
> >>>> >>
> >>>> >> Also, what a lot of people do is issue a query for that information
> as
> >>>> >> needed:
> >>>> >>
> >>>> >> String email = subject.getPrincipal();
> >>>> >> String username = userDAO.getUsername( email );
> >>>> >> //print out the username.
> >>>> >>
> >>>> >> If you have Hibernate 2nd-level caching enabled, and User instances
> >>>> >> are in the 2nd-level cache, this won't 'hit' the database.
 The DAO
> >>>> >> implementation would be something like this (if you have 2nd-level
> >>>> >> cache enabled):
> >>>> >>
> >>>> >> User user = hibernateSession.load( User.class, userId );
> >>>> >> return user.getUsername();
> >>>> >>
> >>>> >> If you don't have 2nd-level cache enabled for users, you'd
have to
> do
> >>>> >> a
> >>>> >> query:
> >>>> >>
> >>>> >> "select u.username from User u where u.id = ?";
> >>>> >>
> >>>> >> HTH,
> >>>> >>
> >>>> >> Les
> >>>> >>
> >>>> >> On Mon, Sep 15, 2008 at 8:19 AM, Animesh Jain <
> animesh@itasveer.com>
> >>>> >> wrote:
> >>>> >> > Hi all
> >>>> >> >
> >>>> >> > I've implemented a custom HibernateRealm by extending
the
> >>>> >> > AuthorizingRealm
> >>>> >> > and things seem to be working pretty good i.e. I'm able
to
> >>>> >> > login/logout
> >>>> >> > users and check roles.
> >>>> >> >
> >>>> >> > Now, on each of my application screens I'd like to print
> something
> >>>> >> > like
> >>>> >> > Hi
> >>>> >> > <Name>. But my logins are done using unique emails
and so, when I
> >>>> >> > try to
> >>>> >> > use
> >>>> >> > the <jsec:principal/> tag the email gets printed.
There's no
> >>>> >> > reference
> >>>> >> > to
> >>>> >> > the user name I have here. How should I go about storing
a user
> >>>> >> > defined
> >>>> >> > principal object here, as I can see the jsec:principal
tag also
> has
> >>>> >> > attributes to retrieve values from a property of a principal
> object.
> >>>> >> > In
> >>>> >> > my
> >>>> >> > case this is a string, how should I set it to something
else.
> >>>> >> >
> >>>> >> > Kind regards
> >>>> >> > Animesh
> >>>> >> >
> >>>> >> >
> >>>> >
> >>>> >
> >>>
> >>>
> >>
> >>
> >
>

Mime
View raw message