Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restrict access by role to a Spring Data REST projection?

In an application using Spring Data JPA and Spring Data REST, let's say you have an entity class like this:

@Entity
public class Person {

   @Id @GeneratedValue
   private int id;

   private String name;

   @JsonIgnore
   private String superSecretValue;

   ...

}

We want Spring Data REST to expose all of this entity's fields EXCEPT for superSecretValue, and so we've annotated that field with @JsonIgnore.

However, in some cases we DO want access to superSecretValue, and so we create a projection that will return all of the fields including that one:

@Projection(name = "withSecret", types = {Person.class})
public interface PersonWithSecret {

   String getName();
   String getSuperSecretValue();

}

Awesome. So now we can access Person entities including the superSecretValue field like this:

curl http://localhost:8080/persons?projection=withSecret

My question is how can we secure that projection? How can we configure things such that anyone can retrieve Person entities without the superSecretValue field... but only people with a certain role (say, ROLE_ADMIN) can use the projection to retrieve the hidden field?

I've found endless examples of using @PreAuthorize or @Secured annotations to secure Spring Data JPA repository CRUD methods (e.g. save(), delete())... but no examples of how to restrict usage of a Spring Data REST projection.

like image 858
Steve Perkins Avatar asked Nov 11 '15 23:11

Steve Perkins


People also ask

What is difference between JpaRepository and CrudRepository?

CrudRepository provides CRUD functions. PagingAndSortingRepository provides methods to do pagination and sort records. JpaRepository provides JPA related methods such as flushing the persistence context and delete records in a batch.

What does the @RepositoryRestResource annotation do?

The @RepositoryRestResource annotation is optional and is used to customize the REST endpoint. If we decided to omit it, Spring would automatically create an endpoint at “/websiteUsers” instead of “/users“. That's it! We now have a fully-functional REST API.

Which dependency is needed for Spring Data project?

We need to add following dependencies for our Spring Data JPA example project. postgresql : Postgresql java driver. spring-core , spring-context : Spring Framework Core dependencies. spring-webmvc , jackson-databind : For Spring REST application.

What is @RepositoryRestController?

Annotation Type RepositoryRestControllerAnnotation to demarcate Spring MVC controllers provided by Spring Data REST. Allows to easily detect them and exclude them from standard Spring MVC handling.


1 Answers

You can overload properties in projections using @Value with conditional SpEL expressions - as in this already answered similar question.

Consider other alternatives (others already mentioned):

  1. Model refactoring. Split entity by access logic (e.g. Person <-> Account)
  2. Adding custom endpoints for special logic and access checks. For example, the current user at "/people/me".
  3. Customising standard endpoints. For example, add custom controller for "/people", "/people/{id}" that would preprocess and return custom Resource type (DTO) depending on on user authorities (e.g. returning PublicPerson instead Person). Then you can write custom resource processors for adding custom links and custom projections for these types.

See also: issue on this subject from spring-data-rest DATAREST-428.

like image 121
aux Avatar answered Oct 06 '22 00:10

aux