Security
Spring Data REST works quite well with Spring Security. This section shows examples of how to secure your Spring Data REST services with method-level security.
@Pre
and @Post
Security
The following example from Spring Data REST’s test suite shows Spring Security’s PreAuthorization model (the most sophisticated security model):
@PreAuthorize("hasRole('ROLE_USER')") (1)
public interface PreAuthorizedOrderRepository extends CrudRepository<Order, UUID> {
@PreAuthorize("hasRole('ROLE_ADMIN')")
@Override
Optional<Order> findById(UUID id);
@PreAuthorize("hasRole('ROLE_ADMIN')") (2)
@Override
void deleteById(UUID aLong);
@PreAuthorize("hasRole('ROLE_ADMIN')")
@Override
void delete(Order order);
@PreAuthorize("hasRole('ROLE_ADMIN')")
@Override
void deleteAll(Iterable<? extends Order> orders);
@PreAuthorize("hasRole('ROLE_ADMIN')")
@Override
void deleteAll();
}
1 | This Spring Security annotation secures the entire repository. The Spring Security SpEL expression indicates that the principal must have ROLE_USER in its collection of roles. |
2 | To change method-level settings, you must override the method signature and apply a Spring Security annotation. In this case, the method overrides the repository-level settings with the requirement that the user have ROLE_ADMIN to perform a delete. |
The preceding example shows a standard Spring Data repository definition extending CrudRepository
with some key changes: the specification of particular roles to access the various methods:
Repository and method level security settings do not combine. Instead, method-level settings override repository level settings. |
The previous example illustrates that CrudRepository
, in fact, has four delete methods. You must override all delete methods to properly secure it.
@Secured security
The following example shows Spring Security’s older @Secured
annotation, which is purely role-based:
@Secured("ROLE_USER") (1)
@RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface SecuredPersonRepository extends CrudRepository<Person, UUID> {
@Secured("ROLE_ADMIN") (2)
@Override
void deleteById(UUID aLong);
@Secured("ROLE_ADMIN")
@Override
void delete(Person person);
@Secured("ROLE_ADMIN")
@Override
void deleteAll(Iterable<? extends Person> persons);
@Secured("ROLE_ADMIN")
@Override
void deleteAll();
}
1 | This results in the same security check as the previous example but has less flexibility. It allows only roles as the means to restrict access. |
2 | Again, this shows that delete methods require ROLE_ADMIN . |
If you start with a new project or first apply Spring Security, @PreAuthorize is the recommended solution. If are already using Spring Security with @Secured in other parts of your app, you can continue on that path without rewriting everything.
|
Enabling Method-level Security
To configure method-level security, here is a brief snippet from Spring Data REST’s test suite:
@Configuration (1)
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true) (2)
class SecurityConfiguration { (3)
...
}
1 | This is a Spring configuration class. |
2 | It uses Spring Security’s @EnableGlobalMethodSecurity annotation to enable both @Secured and @Pre /@Post support. NOTE: You don’t have to use both. This particular case is used to prove both versions work with Spring Data REST. |
3 | This class extends Spring Security’s WebSecurityConfigurerAdapter which is used for pure Java configuration of security. |
The rest of the configuration class is not listed, because it follows standard practices that you can read about in the Spring Security reference docs.