There are a number of ways to solve this.

One way is that you assign permissions to a user that reflect the
instances they can interact with.

For example, if you assign the user the "post:read" permission (using
Shiro's WildcardPermission syntax), then that user will be able to
read all posts, e.g. subject.isPermitted("post:read") === true

You can further assign permissions according to individual Post
instances.  Maybe you assign a permission at the time the user creates
the post:

Post post = new Post();
...
long postId = postDAO.create(post);
String editPostPermString = "post:edit:" + postId;

long currentUserId = (long)SecurityUtils.getSubject().getPrincipal();

userService.assignPermission(currentUserId, editPostPermString);

Then, when a user visits a post page, you can check:

if ( SecurityUtils.getSubject().isPermitted("post:edit:" + requestPostId) ) {
    //show the edit button
}
if ( SecurityUtils.getSubject().isPermitted("post:edit") ) {
    //general read request by anyone - show the post.
}

Don't forget to 'unassign' the permission from the user when you
delete the post to make sure you don't have 'permission assignment
orphans'.  The downside of this approach is that the number of
individual permissions assigned to the user can be very large, so your
Realm implementation and the data model supporting the permission
checks must be efficient.

Another approach is to combine the WildcardPermission check and a data
model check:

For example:

Post post = blogService.getPost(request.getParameter("postId"));

boolean read = SecurityUtils.getSubject().isPermitted("post:read");
boolean edit = isPostEditable(post);

private boolean isPostEditable(Post post) {
    User currentUser =
userService.findUser(SecurityUtils.getSubject().getPrincipal());
    if (currentUser.getId() == post.getAuthor().getId()) {
        return true;
    }
    return false;
}

You could also find this out via a join query:

select p.author_id from posts p where p.id = ?

As you can see, the 2nd approach is _very_ dependent upon your data
model, so it would be difficult for Shiro to support this 'out of the
box'.  If anyone has any ideas that can make this even easier, please
speak up!

This is just a high-level approach of how you might do this in your
own app, but hopefully this gives you some ideas.

HTH,

Les


On Wed, Dec 1, 2010 at 12:30 PM, acec acec <[email protected]> wrote:
> Hi, all
> If I want to support the following function by shiro:
>
> The user can read all post, but can only edit/delete his own post.
>
> Is there any example for this kind of function?
>
> Thanks.
> Acec

Reply via email to