[[security]]
= Security
:spring-security-docs: https://docs.spring.io/spring-security/reference

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.

[[security.pre-and-post]]
== `@Pre` and `@Post` Security

The following example from Spring Data REST's test suite shows Spring Security's {spring-security-docs}/servlet/authorization/expression-based.html#_access_control_using_preauthorize_and_postauthorize[PreAuthorization model] (the most sophisticated security model):

.spring-data-rest-tests/spring-data-rest-tests-security/src/test/java/org/springframework/data/rest/tests/security/PreAuthorizedOrderRepository.java
====
[source,java]
----

include::example$security/PreAuthorizedOrderRepository.java[tag=code]
----

<1> This Spring Security annotation secures the entire repository. The {spring-security-docs}/servlet/authorization/expression-based.html[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:

IMPORTANT: 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.

[[security.secured]]
== @Secured security

The following example shows Spring Security's older `@Secured` annotation, which is purely role-based:

.spring-data-rest-tests/spring-data-rest-tests-security/src/test/java/org/springframework/data/rest/tests/security/SecuredPersonRepository.java

====
[source,java]
----
include::example$security/SecuredPersonRepository.java[tag=code]
----

<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`.
====

NOTE: 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.

[[security.enable-method-level]]
== Enabling Method-level Security

To configure method-level security, here is a brief snippet from Spring Data REST's test suite:

.spring-data-rest-tests/spring-data-rest-tests-security/src/test/java/org/springframework/data/rest/tests/security/SecurityConfiguration.java
====
[source,java]
----
include::example$security/SecurityConfiguration.java[tag=code]
	...
}
----

<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 {spring-security-docs}/servlet/configuration/java.html[standard practices] that you can read about in the Spring Security reference docs.
