... or, instead of that very complicated ( ;) ) and high-counted-permission (as many perm as many posts in system multiple 3) solution that Les proposed, use spatial permissions, and just define a finite PostAuthorSpace, and allow editing/deleting for all posts that has 0 distance from current user.
Les, sorry, I could not resist ;) Thanks, ~t~ On Wed, Dec 1, 2010 at 10:34 PM, Les Hazlewood <[email protected]>wrote: > Oops. In the instance-level approach, the 2nd code check would be: > > if (SecurityUtils.getSubject().isPermitted("post:read:" + postId) ) { > //show the post > } > > This is the correct check to execute at runtime - an instance-specific > check, and _not_ SecurityUtils.getSubject().isPermitted("post:read")). > This latter check (isPermitted("post:read")) says "if the current > user has the ability to read all posts, show the current post". This > is slightly incorrect, because what you _really_ want to check is > "does the current user have the ability to read the current post". > The difference is subtle, but it is a crucial point to understand when > using implication logic to build security policies. > > If the user is assigned the "post:read" permission, then that > _implies_ post:read:postId Runtime permissions checks should be as > specific as possible, while permission assignments can be (and usually > are) more general (e.g. "post:read"). > > Regards, > > Les > > On Wed, Dec 1, 2010 at 1:26 PM, Les Hazlewood <[email protected]> > wrote: > > 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 >
