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