Spring Boot MVC non-role based security

403 views Asked by At

I am attempting to setup security in a new Spring Boot MVC application. I am attempting to do this with no XML configuration, only Java. Currently I have been able to get role based security working using the @Secured annotation on each of my @RequestMapping methods.

I also need to add object based security, for example:

User has been granted access to widget ID 456 and 689, and is unable to access any other widget. This is clearly not something that can be accomplished using role based security as there can be theoretically unlimited number of different widgets that various users could have access to.

To do this, it is my understanding I needed to create new AccessDecisionVoter and GrantedAuthority implementations that determine if a user has the appropriate authority to access the widget.

Unfortunately, I have not been able to determine how this needs to be implemented, I am looking for any examples that describe how to setup security based on similar requirements.

1

There are 1 answers

2
jgr On BEST ANSWER

Maybe @PreAuthorize or @PostAuthorize will be enough for you, it depends what exactly you need. You can try something like this:

@PostAuthorize("returnObject.widget.owner.id == principal.id")
public Widget getWidgetById(long id) {
   // ...
return widget;
}

Update

You can use Pre/Post Authorize since Spring Security 3.0 and as you said it provides more advanced features over @Secured. In pre/post annotations you can use SpeL (Spring expression language).

If you want use pre/post annotations you need this in config:

<global-method-security pre-post-annotations="enabled" />

Example: Let user with ROLE_USER add posts with text field contain less than 140 characters and users with role ROLE_PREMIUM add posts with any length

@PreAuthorize("(hasRole('ROLE_USER') and #post.text.length() <= 140)
  or hasRole('ROLE_PREMIUM')")

If any of Spring Security annotation and Spel doesn't let you make required access rule its also possible to use custom methods in PreAuthorize (but I actually don't know if it's good practice):

@PreAuthorize("hasRole('ROLE_ADMIN') 
or @mySecurityService.isPostOwner(#post_id, principal.id))")