Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security - Ownership based access

Let's say I've a minimal RESTful controller like the following, by the way using Java 8 and Spring Boot 2, ...

@RestController
class MyController {

    @Autowired
    private PostService service;    

    @GetMapping
    public Post get() {

        return service.getLatest();
    }
}

I've secured this route successfully using the Spring Security module. Now I want to allow only the resource owner access to this resource. With resource owner I mean the creator or saying it simple:

Post myPost = new Post();
...
myPost.getCreator().equals(currentUser); // Should be true when access is granted

I found a lot about role based access, but nearly nothing for checking ownership... Of course I could place an if statement inside of the controller and throw an exception, but I intended to use something like Spring's Expression-Based Access Control.

Any other ideas? Does somebody have a good idea or example for ownership checking of a resource?

like image 452
0x1C1B Avatar asked Jul 03 '19 13:07

0x1C1B


People also ask

How do you allow a user only access their own data in spring boot?

In any @Controller , @RestController annotated bean you can use Principal directly as a method argument. @RequestMapping("/users/{user_id}") public String getUserInfo(@PathVariable("user_id") Long userId, Principal principal){ // test if userId is current principal or principal is an ADMIN .... }

What's the difference between @secured and @PreAuthorize in Spring Security?

The real difference is that @PreAuthorize can work with Spring Expression Language (SpEL). You can: Access methods and properties of SecurityExpressionRoot . (Advanced feature) Add your own methods (override MethodSecurityExpressionHandler and set it as <global-method-security><expression-handler ... /></...> ).

What is hasRole and hasAnyRole?

Description. hasRole([role]) Returns true if the current principal has the specified role. hasAnyRole([role1,role2]) Returns true if the current principal has any of the supplied roles (given as a comma-separated list of strings)

What are access controls in Spring Security?

Access Control List (ACL) is a list of permissions attached to an object. An ACL specifies which identities are granted which operations on a given object. Spring Security Access Control List is a Spring component which supports Domain Object Security.


1 Answers

For a simple get operation you can just return the post linked to your current logged in user

@GetMapping
public Post getPost(Authentication authentication) {
    return service.getPostByUser(authentication.getName());
}

For updating an existing post, you can check within the PreAuthorize if the creator is the logged in user. authentication.getName() gives back an email in my example

@PutMapping
@PreAuthorize("#post.getCreator() == authentication.getName()")
public void update(@RequestBody Post post, Authentication authentication) {
    service.updatePost(post);
}

Basic example of the @Component way

@Autowired
private CreatorCheck creatorCheck;

@PutMapping
@PreAuthorize("@creatorChecker.check(#post,authentication)")
public void update(@RequestBody Post post, Authentication authentication) {
    service.updatePost(post);
}

And the component.. Can be extended to retrieve the original Post and check that creator..

@Component
public class CreatorCheck {

    public boolean check(Post post, Authentication authentication) {
       return post.getCreator().equals(authentication.getName());
    }
}

For a more comprehensive tutorial check out this tutorial link found by 0x1C1B

like image 143
Joeri Boons Avatar answered Sep 18 '22 10:09

Joeri Boons