Setting user roles based on some kind of ownership

2019-02-16 19:51发布

问题:

In my Spring-based application, I currently have basic roles such as ADMIN, and USER.

Is it possible to define a user role such as PHOTO_UPLOADER, which inherits from USER, but also adds a check whether the user making the call is actually the owner of the photo?

I am tired of writing the same if (currentUser.id == photo.uploader.id) in my controller actions over and over again. It applies to other entities as well.

回答1:

You can handle it with ACLs like Tomasz Nurkiewicz suggested. But Spring Securitz ACLs are complex and poor documented. (The best resource I know for it is this Book: Spring Security 3 - by the authors of Spring Security)

But If you really need only this simple if (currentUser.id == photo.uploader.id) test, then I would recommend an other technique.

It is possible to enhance the method security expressions you can use them in @PreAuthorize annotations. Like:

@PreAuthorize("isPhotoOwner(#photo)")
public void doSomething(final Photo photo) {

To implement such an expression isPhotoOwner the core is really simple:

public class ExtendedMethodSecurityExpressionRoot extends MethodSecurityExpressionRoot {

    public ExtendedMethodSecurityExpressionRoot(final Authentication a) {
        super(a);
    }

    /**
     * 
     */
    public boolean isPhotoOwner(final Photo photoObject) {
        if (photoObject == null) {
            return false;
        }

        Photo photo = (photo) photoObject;
        return photo.getCreator().getLogin().equals(authentication.getName());
    }
}

Unfortunaly there is some addtional work to to register the ExtendedMethodSecurityExpressionRoot. --- I have no time at the moment, if you are willing to try this approach, then leave a commment, and I will descripe the rest



回答2:

i don't know what types of data accessing technology you are using. i know you can write interceptor or event listener to do the security checking for hibernate. i think ibatis is also the same way. in my project, i wrote CRUD enable interface methods in the parent model/entity class, and doing security check in some events, such as before entity loading. spring security acl is a bit complex. implementing your security solution is more better.



回答3:

Welcome in the world of ACLs - access control list. This tutorial is rather old but pretty comprehensive.