One of the first steps in Spring Security is to configure request matching. Request matching allows us to define how the incoming request should be matched to the given security configuration.
In order to define request matching, we need to always define two things:
Defining request matching is done as most things in Spring Security, by using the HttpSecurity
object. We invoke
authorizeHttpRequests
where for given AbstractRequestMatcherRegistry
we define the endpoints.
Then, we will receive AuthorizationManagerRequestMatcherRegistry
where we can define how we want to secure our endpoints.
For instance setting all endpoints to be accessible only by authenticated users is done by:
authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
AbstractRequestMatcherRegistry
has following methods for defining request matching:
anyRequest()
- selecting all endpoints.requestMatchers(HttpMethod method, String... patterns)
- selecting endpoints based on HTTP method and patterns.requestMatchers(HttpMethod method)
- selecting endpoints based on HTTP method.requestMatchers(String... patterns)
- selecting endpoints based on patterns.mvcMatchers(RequestMatcher... requestMatchers)
- selecting endpoints based on RequestMatcher
definition we provide.AuthorizationManagerRequestMatcherRegistry.AuthorizedUrl
has following methods for defining security:
permitAll()
- allowing all requests.denyAll()
- denying all requests.authenticated()
- allowing only authenticated requests.hasRole(String role)
- allowing only requests from users with given role.hasAuthority(String authority)
- allowing only requests from users with given authority.access(AuthorityAuthorizationManager authorityAuthorizationManager)
- we can define our
own AuthorityAuthorizationManager
to define how we want to secure our endpoints.and many more.
Let’s start with the simplest example. Let’s assume we have enabled basic authentication in our application. How to set up Spring Security to use basic authentication you can read in my previous article Spring Boot Basic Auth.
Now, if we want to secure all endpoints in our application to be only accessible by authenticated users, we need to define the following configuration:
@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated()).httpBasic(withDefaults());return http.build();}
If we want to define pattern based on which we will select endpoints, we can use requestMatchers
method.
For instance, if we want to allow users with role USER to access GET endpoints starting with /user/
we can do it as follows:
@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize.requestMatchers(HttpMethod.GET, "/user/**").hasRole("USER").anyRequest().authenticated()).httpBasic(withDefaults());return http.build();}
On the other hand, we might want ADMIN users to have access to all endpoints. We can do it as follows:
@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize.requestMatchers(HttpMethod.GET, "/user/**").hasRole("USER").anyRequest().hasRole("ADMIN")).httpBasic(withDefaults());return http.build();}
Last but not least, we can define our own RequestMatcher
to define how we want to match the request.
For instance, we can define our own RequestMatcher
which will match only requests with X-My-Custom-Header
header.
@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated().requestMatchers(HttpMethod.GET, "/user/**").hasRole("USER").requestMatchers(new ParamterRequestMatcher()).permitAll().anyRequest().hasRole("ADMIN")).httpBasic(withDefaults());return http.build();}private static class ParamterRequestMatcher implements RequestMatcher {@Overridepublic boolean matches(HttpServletRequest request) {return request.getHeader("X-My-Custom-Header") != null;}}
In this article, we have learned how to define request matching in Spring Security. Request matching is basically defining which endpoints we want to secure and how we want to secure them. Please try it out and let me know what you think!
Quick Links
Legal Stuff