To give you a background, we have an application with lots of REST services. Now for these services there are security permission entries. Now we could have an AccessVoter
that intercepts all the request to check whether the user has permission to a resource but this is inefficient as we have to load thousands of rows from database and check the incoming request with the pattern saved in database. The pattern that I mentioned is exactly the same as the pattern that the developer put in their REST method, for example:
@PostMapping(value = "/accounts/{id}/advisers/{adviserId}")
Or
@PostMapping(value = "/accounts/{id}/advisers/address/{adrId}")
You can see how complex it can be and going through the records to find a match is expensive while Spring has already done the mapping and it can find the associated method very nicely.
We could create an aspect to check the permissions before the method invocation but at that time is too late as there are validation layers that happens before
I was thinking if we could have an access voter and then ask Spring to give us the method that it's going to invoke so that we can read the annotation, in above example @PostMapping
and then find the pattern (say e.g. /accounts/{id}/advisers/{adviserId}
) so we can only query that pattern from database, then this will be very efficient and less complex in our code.
The question is whether it's possible to get this information from Spring Boot or not?
Is there any other way than using Spring's AccessVoter
to do the job? For example when we configure ResourceServerConfigurationAdaptor
we have this code:
http.authorizeRequests()
.antMatchers(oAuth2AuthenticationSettings.getProtectedUrlPattern().split(","))
.authenticated().accessDecisionManager(accessDecisionManager);
As you can see accessDecisionManager
is the one that returns AccessVoter
but we could also set .authenticated().expressionHandler(...)
which I don't know what it is used for. Can it be used for our purposes?
We don't want to use @PreAuthorize
as it means we have to go and annotate all of our REST services.