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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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
<[EMAIL PROTECTED]> 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
<[EMAIL PROTECTED]>
>> 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
>> >
>> >
>
>