You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Tauren Mills <yo...@gmail.com> on 2009/07/04 22:03:01 UTC

Re: wicket-ki-security

Les,

Thanks for posting this to the user list and your suggestions. The
wicket-shiro project already had UserService implemented the way you
suggested, but I just wasn't using it effectively in UserAuthHeader.  I've
updated the UserAuthHeader to call getCurrentUser().  I have not added a
ShiroService to the wicket-shiro sample, but I can see how it would prove
useful in a real project. Perhaps I'll add it to the sample later.

So I'm curious about the status of getting Shiro into a maven repository.
Any estimates on when that might happen?

Thanks!
Tauren


On Sat, Jun 27, 2009 at 12:38 PM, Les Hazlewood <lh...@apache.org>wrote:

> Hi Tauren,
>
> I'm forwarding this to the Shiro user list as the answer could benefit
> other people as well.
>
> The User object itself should probably never be stored in the Subject or
> its Session - just the ID as you've pointed out.  This is definitely the
> appropriate way to use Shiro for most enterprise applications.
>
> The reason is that, especially with JPA/Hibernate applications, If Shiro
> stored the User object directly, it would bypass lots of optimizations that
> are in place in persistence frameworks, such as caching.
>
> That is, you should almost always lookup the User object during a
> transaction via the Subject-accessible user ID, and rely on a nice caching
> framework to improve performance if you don't want an expensive 'round trip'
> to the database each time you do the lookup.
>
> This is especially important for coherency - if you cache a User object in
> the Subject (or the Subject's Session), and you change that User object
> somewhere else in the application (say, via an 'update account' web page),
> well, now the User object in your session is 'stale' and does not reflect
> the one changed by visiting the 'update account' web page.
>
> This beneficial technique is not unique to just Shiro of course - most
> session values should usually be extremely lightweight objects - ids or
> lookup keys to pull the corresponding 'real' object via a Service or DAO
> call, relying on the underlying persistence framework and caching to help
> with performance, data versioning, coherency, etc.
>
> So a good practice is to have a 'utility' helper component that can do this
> translation automatically.
>
> For example, UserService#getCurrentUser():
>
> public User getCurrentUser() {
>     Long id = (Long)SecurityUtils.getSubject().getPrincipal();
>     if ( id != null ) {
>         // they are either authenticated or remembered from a previous
> session,
>         // so return the user:
>         return getUser(id);
>     } else {
>         //not logged in or remembered:
>         return null;
>     }
> }
>
> I've taken this concept a little further and I wrap all my
> SecurityUtils.getSubject().* method operations by creating a SubjectService
> interface:
>
> public interface SubjectService {
>
>     User getCurrentUser();
>
>     hasRole(String role);
>
>     isPermitted(String permission);
>
>     //more Subject 'wrapper' methods as necessary
>
>     setSessionAttribute(Object key, Object value);
>     removeSessionAttribute(key);
>
>     //etc..
> }
>
> Then you would write a ShiroSubjectService implementation of this
> interface that calls the Shiro SecurityUtils/Subject API.
>
> The benefit here is that all of your code deals with the SubjectService for
> everything, and never needs to 'know about', i.e. import any of Shiro's
> APIs - very loosely coupled.  Granted, you wouldn't need to use such an
> abstraction for wicket-shiro integration, but this approach is very useful
> in enterprise applications where you want to decouple you and your
> programming team from any 3rd party APIs as best as possible.
>
> I hope that helps!
>
> Cheers,
>
> Les
>
>
> On Sat, Jun 27, 2009 at 12:52 PM, Tauren Mills wrote:
>
>> Les,
>>
>> Just wanted to let you know I renamed the project to wicket-shiro.  I also
>> added a spring/hibernate example to it.  But I was wondering if I should be
>> getting the username out of the subject in a better way than this:
>>
>> @SpringBean(name = "userService")
>> private UserService userService;
>>
>> public UserAuthHeader(String id, Class<? extends Page> loginPage)
>> {
>>   super( id );
>>
>>   add( new Label( "name", new AbstractReadOnlyModel<String>() {
>>     @Override
>>     public String getObject() {
>>       Long id = (Long) SecurityUtils.getSubject().getPrincipal();
>>       return userService.getUser(id).getUsername();
>>     }
>>   }) );
>> }
>>
>> With the user being a Hibernate User entity, the principle is a Long id.
>> So I'm using that to find the User from the userService and return the
>> username. But is the User object stored in the Subject somewhere? I didn't
>> locate it when I was tracing the code.
>>
>> See here for the full java file:
>>
>> https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/trunk/wicketstuff-core/shiro-security/wicket-shiro-examples/shiro-example-spring-hibernate/src/main/java/org/wicketstuff/shiro/example/sprhib/UserAuthHeader.java
>>
>> Thanks!
>> Tauren
>
>
>