souser
souser

Reputation: 798

Spring MVC custom authorization/security for controller methods

Looking to create a custom implementation to authorize requests.

I am evaluating options to avoid using annotations on every method in the controller. Instead, I am exploring the possibility centralizing this feature via a filter that checks if the logged in user has the required permission for the URL

We are using Spring 3.2.5.RELEASE

I intend to create a database table that has a mapping between a permission and the relevant URL.

I am looking for a way to get the request mapping information for the current URL.

For E-g : In my database, I have:

    URL=/view/{id} , permission=VIEW_USER

If the current URL is :

    /app/user/view/1

, a method annotated with

    @RequestMapping(value = "/view/{id}", method = RequestMethod.GET)

will be invoked. But before this happens, I need to verify if the logged in user has the permission to view user details.

In my filter, I can get the current URL (/app/user/view/1) , how do I get the corresponding mapping (/view/{id}) ? Is there a mechanism to match a URL to its corresponding MVC request mapping ?

I have looked/am looking at related posts on SO and also looked at Spring code but am yet to find a way.

Upvotes: 0

Views: 2323

Answers (1)

Krešimir Nesek
Krešimir Nesek

Reputation: 5512

If you want to do it that way, you could register MVC interceptor instead of servlet filter. Create a class that extends HandlerInterceptorAdapter and in preHandle method you will have access to controller's method and it's annotation. Prehandle method of your interceptor could look something like this:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    if (handler instanceof HandlerMethod) {
        HandlerMethod method = (HandlerMethod) handler;
        if (method.getMethod().isAnnotationPresent(RequestMapping.class)) {
            RequestMapping rqm = method.getMethodAnnotation(RequestMapping.class);
            String[] urlMappings = rqm.value();
            //do security logic
        }
    }
    ...
}

Then you need to register the interceptor. If you use xml config it's done like this:

<mvc:interceptors>
  <bean class="com.example.MySecurityInterceptor" />
  ...
</mvc:interceptors>

Please note that your approach will be difficult, you'll need to handle all the request mapping cases that spring supports. For example, @RequestMapping that's annotated on class level. Or @RequestMapping annotated on parent class of the controller etc..

Upvotes: 1

Related Questions