No problem Animesh - I'm happy to help :)
On Mon, Sep 15, 2008 at 2:36 PM, Animesh Jain <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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 <[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
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >
>> >> >>>> >
>> >> >>>
>> >> >>>
>> >> >>
>> >> >>
>> >> >
>> >
>> >
>
>