Relax Security for Spring Data REST Projection

I have a User class, and I want to allow access in such a way that only the user can see what he is entitled to.

This was easily achievable with Spring Security combined with Spring Data Rest, where in the JPA repository I did below -

public interface UserRepository extends JPARepository<User,Integer> { @PreAuthorize("hasRole('LOGGED_IN') and principal.user.id == #id") User findOne(@Param("id") Integer id); } 

This way the user, visiting Spring Data REST, aligns the URLs, for example -

 /users/{id} /users/{id}/userPosts 

Only those who are logged in with {id} will be able to see them, and everyone else will receive 401, as I would like.

My problem is that I have one of the Projections, which is publicly available for each user, and I break it up with Spring Data Rest forecasts, as below, where I want to be accessible for each {id}

 @Projection(name = "details", types = User.class) public interface UserDetailsProjection { .. } 

So, /users/{id1}?projection=details , as well as /users/{id2}?projection=details should give 200 OK and show the data, even if the user is registered on {id1}

I started to implement this by noting the projection with @PreAuthorize ("allowAll"), but that will not work, since the repository has a more complicated security check. Can we have this functionality where for projection we can weaken security?

I use the latest Spring Data Rest and Spring Security Distributions

+5
source share
2 answers

It seems reasonable to add a custom controller for this use case.

Please also consider:

  • Rate projection access with @Value annotations
  • Add another object for the same database data, but with a different field set for read-only operations, for example. using inheritance (be careful with caching, etc.) - depends on the type of data store
  • Modify the model to separate the User object into two different objects (profile, account), since they seem to have different access and, possibly, even operations
  • You can also add a ResourceProcessor<UserSummaryProjection> to programmatically evaluate access and replace resource content (projection) using DTO

An example of access assessment in projections with @Value annotations:

 @Projection(types = User.class, name = "summary") public interface UserSummaryProjection { @Value("#{@userSecurity.canReadEmail(target) ? target.email: null}") String getEmail(); } 
+2
source

Added spring security code at the data access level - this is not a good idea. I would suggest you add the @PreAuthorize annotation to the controller / service method. Since you have a query parameter ?projection=details , you can have a separate management / service method for projecting details.

Add the following forecast method:

 @RequestMapping("/url", params = {"projection"}) @PreAuthorize("hasRole('LOGGED_IN') and principal.user.id == #id") 
0
source

Source: https://habr.com/ru/post/1213596/


All Articles