You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Animesh Jain <an...@itasveer.com> on 2008/09/15 14:19:06 UTC

How to set a custom principal object

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

Re: How to set a custom principal object

Posted by Les Hazlewood <le...@hazlewood.com>.
Animesh,

If you could please open a Jira issue for the 'index' attribute on the
jsec:principal taglib, we could support easy access to any object in
the principal collection - primitive or not.

On Mon, Sep 15, 2008 at 1:28 PM, Animesh Jain <an...@itasveer.com> 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 <le...@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 <an...@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 <le...@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 <an...@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
>> >> >
>> >> >
>> >
>> >
>
>

Re: How to set a custom principal object

Posted by Animesh Jain <an...@itasveer.com>.
Will file a Jira shortly Les - got busy with other stuff again. And I'll
file another one for the Guice Web configuration later (separate thread) -
still trying to get the structure of that config a little better as I'm
myself new to using Guice. I think it'll also need some better documentation
as Guice is not widely used as Spring is.

Animesh

On Tue, Sep 16, 2008 at 12:26 AM, Les Hazlewood <le...@hazlewood.com> wrote:

> No problem Animesh - I'm happy to help :)
>
> On Mon, Sep 15, 2008 at 2:36 PM, Animesh Jain <an...@itasveer.com>
> wrote:
> > aah! I knew I was missing something simple here. Sorry to keep bothering
> you
> > Les, you're a great help though.
> >
> > Cheers
> > Animesh
> >
> > On Mon, Sep 15, 2008 at 11:53 PM, Les Hazlewood <le...@hazlewood.com>
> wrote:
> >>
> >> Looks good.  Instead of passing in the username to
> >> buildAuthenticationInfo, you'd just pass in your 'composite' object.
> >>
> >> On Mon, Sep 15, 2008 at 2:18 PM, Animesh Jain <an...@itasveer.com>
> >> wrote:
> >> > 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 <le...@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
> >> >> >>>> <an...@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
> >> >> >>>> > <le...@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
> >> >> >>>> >> <an...@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
> >> >> >>>> >> >
> >> >> >>>> >> >
> >> >> >>>> >
> >> >> >>>> >
> >> >> >>>
> >> >> >>>
> >> >> >>
> >> >> >>
> >> >> >
> >> >
> >> >
> >
> >
>

Re: How to set a custom principal object

Posted by Les Hazlewood <le...@hazlewood.com>.
No problem Animesh - I'm happy to help :)

On Mon, Sep 15, 2008 at 2:36 PM, Animesh Jain <an...@itasveer.com> wrote:
> aah! I knew I was missing something simple here. Sorry to keep bothering you
> Les, you're a great help though.
>
> Cheers
> Animesh
>
> On Mon, Sep 15, 2008 at 11:53 PM, Les Hazlewood <le...@hazlewood.com> wrote:
>>
>> Looks good.  Instead of passing in the username to
>> buildAuthenticationInfo, you'd just pass in your 'composite' object.
>>
>> On Mon, Sep 15, 2008 at 2:18 PM, Animesh Jain <an...@itasveer.com>
>> wrote:
>> > 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 <lh...@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 <le...@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 <an...@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 <jh...@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 <le...@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
>> >> >>>> <an...@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
>> >> >>>> > <le...@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
>> >> >>>> >> <an...@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
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >
>> >> >>>> >
>> >> >>>
>> >> >>>
>> >> >>
>> >> >>
>> >> >
>> >
>> >
>
>

Re: How to set a custom principal object

Posted by Animesh Jain <an...@itasveer.com>.
aah! I knew I was missing something simple here. Sorry to keep bothering you
Les, you're a great help though.

Cheers
Animesh

On Mon, Sep 15, 2008 at 11:53 PM, Les Hazlewood <le...@hazlewood.com> wrote:

> Looks good.  Instead of passing in the username to
> buildAuthenticationInfo, you'd just pass in your 'composite' object.
>
> On Mon, Sep 15, 2008 at 2:18 PM, Animesh Jain <an...@itasveer.com>
> wrote:
> > 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 <lh...@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 <le...@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 <an...@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 <jh...@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 <le...@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
> >> >>>> >> <an...@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
> >> >>>> >> >
> >> >>>> >> >
> >> >>>> >
> >> >>>> >
> >> >>>
> >> >>>
> >> >>
> >> >>
> >> >
> >
> >
>

Re: How to set a custom principal object

Posted by Les Hazlewood <le...@hazlewood.com>.
Looks good.  Instead of passing in the username to
buildAuthenticationInfo, you'd just pass in your 'composite' object.

On Mon, Sep 15, 2008 at 2:18 PM, Animesh Jain <an...@itasveer.com> wrote:
> 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 <lh...@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 <le...@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 <an...@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 <jh...@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 <le...@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 <an...@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 <le...@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
>> >>>> >> <an...@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
>> >>>> >> >
>> >>>> >> >
>> >>>> >
>> >>>> >
>> >>>
>> >>>
>> >>
>> >>
>> >
>
>

Re: How to set a custom principal object

Posted by Animesh Jain <an...@itasveer.com>.
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 <lh...@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 <le...@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 <an...@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 <jh...@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 <le...@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 <an...@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 <le...@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
> >>>> >> >
> >>>> >> >
> >>>> >
> >>>> >
> >>>
> >>>
> >>
> >>
> >
>

Re: How to set a custom principal object

Posted by Les Hazlewood <lh...@apache.org>.
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 <le...@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 <an...@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 <jh...@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 <le...@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 <an...@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 <le...@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 <an...@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
>>>> >> >
>>>> >> >
>>>> >
>>>> >
>>>
>>>
>>
>>
>

Re: How to set a custom principal object

Posted by Les Hazlewood <le...@hazlewood.com>.
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 <an...@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 <jh...@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 <le...@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 <an...@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 <le...@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 <an...@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
>>> >> >
>>> >> >
>>> >
>>> >
>>
>>
>
>

Re: How to set a custom principal object

Posted by Animesh Jain <an...@itasveer.com>.
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 <jh...@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 <le...@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 <an...@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 <le...@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 <an...@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
>> >> >
>> >> >
>> >
>> >
>>
>
>
>

Re: How to set a custom principal object

Posted by Jeremy Haile <jh...@fastmail.fm>.
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 <le...@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 <an...@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  
> <le...@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  
> <an...@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
> >> >
> >> >
> >
> >
>


Re: How to set a custom principal object

Posted by Animesh Jain <an...@itasveer.com>.
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 <le...@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 <an...@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 <le...@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 <an...@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
> >> >
> >> >
> >
> >
>

Re: How to set a custom principal object

Posted by Les Hazlewood <le...@hazlewood.com>.
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 <an...@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 <le...@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 <an...@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
>> >
>> >
>
>

Re: How to set a custom principal object

Posted by Animesh Jain <an...@itasveer.com>.
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 <le...@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 <an...@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
> >
> >
>

Re: How to set a custom principal object

Posted by Les Hazlewood <le...@hazlewood.com>.
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 <an...@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
>
>