By Marone: November 2020 | last update: December 2020
Secure API with spring method security
Goal
In all previous spring security articles we used HttpSecurity to restrict http requests. In this article we will explore another way to use spring security in order to secure spring boot REST API.
The spring security provides a great feature called "Method security", which allows us to use annotations like @PreAuthorize or @Secured to secure API's in fine-grained manner.
@PreAuthorize vs @Secured
There is a lot of stuff about this topic, but the significant difference is the fact that PreAuthorize supports Spring Expression Language (SpEL), which is very powerful.What we need
Keycloak 8.0.1Java 11
Maven 3.x
curl 7.65
jq 1.5
Maven dependencies
Additionally to spring security and web dependencies we need also the keycloak spring boot adapter,
keycloak-spring-boot-starter
.
Config
@KeycloakConfiguration provides other Spring security configuration such as @EnableWebSecurity, @Configuration, ...etc.
Afer that we will enable using MethodSecurity , in this case we enabled exactly the usage of
@PreAuthorize, @PostAuthorize and @Secured
On line 11 we use SimpleAuthorityMapper, which adds the prefix
ROLE_
to keycloak roles.
Between lines 25 and 26 we specified that all endpoints expect the root
/
are restricted and requires an Authentication
Securing REST API
Let's take a look on the controller class, it provides four operations::
- The first operation is public, there is no restriction
- The second one uses @PreAuthorize annotation, it requires a authenticated user with the role = USER
- The third one use @Secured annotations, which requires a authenticated user with the role = ROLE_USER
- The last one is similar to the second one except the role should be equal to ADMIN.
Keycloak configuration
Keycloak Spring Boot Adapter will read the needed configuration from application.properties file.The three first properties are required, the name of realm is wstutorial,
keycloak.auth-server-url
points the Keycloak server and with keycloak.resource
we define the client-id which is public.