Reputation: 4327
I have a Spring web service where users only have access to specific resources. Any user can make a request to get the resource info, but I need to throw an Authorization exception if they don't have access to that resource. The API is as follows:
GET /resources/{resourceId}
The above API provides the user all info about a given resource.
Currently I do authentication using WebSecurityConfigurerAdapter
. To add authorization, I have observed that I can set the granted authorities as part of the Authentication object. On doing so, I can use something like @PreAuthorize("hasRole('ROLE_USER')")
to do the authorization.
However, for the mentioned API I am not sure if the mentioned authorization approach is suitable for the following reasons.
resourceId
. This is not exactly a Role. More like a Privilege. Is it still acceptable to use hasRole()
for this use case? hasRole()
annotation I would need to do something like @PreAuthorize("hasRole('ACCESS_RESOURCEID12346')")
where RESOURCEID12346
is the resourceId
. But, we only have access to resourceId
once we are in the API controller. So, how do I use that value for the authorization annotation? If the specified approach is not the best way of solving the problem, I would appreciate any input/feedback on what would be the best approach. I'd like to avoid doing this check in the controller. I am trying to do it through Spring Security similar to how @PreAuthorize works. I think access to the resourceId is an authorization requirement and we should not even get into the API controller if the user doesn't have access to that resource.
Upvotes: 3
Views: 2749
Reputation: 13930
Distributing permissions through roles bound to a resource id seems like a potential maintenance nightmare. If you don't want to allow access to the controller then maybe access
is the best thing to use.
The above link has examples for both Java and xml based configuration and shows how you can gain access to the path before entering the controller.
You would provide a method that you reference like:
boolean checkResourceAccess(Principal principal, int resourceId)
In your config you refer to the url argument like #resourceId
mapping it to {resourceId}
.
Java config example:
http.authorizeRequests()
.antMatchers("/resources/{resourceId}")
.access("@yourBean.checkResourceAccess(principal,#resourceId)")...
In that method you supply whatever logic needed to determine the user's access.
Upvotes: 4