tangent
tangent

Reputation: 388

Spring Pre/Post method security annotations not working

I can't seem to get Spring Pre/Post method security annotations to work. I've read every related stackoverflow question on the topic, and the main suggestion is to ensure that global-method-security is enabled in the same context as the beans which you wish to secure. I have the following my dispatcher-servlet.xml:

  <context:component-scan base-package="com.package.path" />
  <context:annotation-config />
  <security:global-method-security pre-post-annotations="enabled" />

The beans in question are in "com.package.path". I know that Spring is creating instances of them correctly, as injection is working just fine and requests are being serviced by the intended classes.

So, here's an example service class in "com.package.path":

@Controller
@RequestMapping("/article")
public class ArticleServiceImpl extends GWTController implements ArticleService {
    @Autowired
    public ArticleServiceImpl(DataSource ds) {

    }

    @Override
    @PreAuthorize("hasRole('ROLE_BASIC_USER')")
    public Article save(Article article) {

    }

}

The annotation on the save method does not work. A few important notes:

Here's my GWTController class, referenced above, if needed:

package com.areahomeschoolers.baconbits.server.spring;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.ServletConfigAware;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.areahomeschoolers.baconbits.server.util.ServerContext;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * Spring controller class that handles all requests and passes them on to GWT. Also initializes server context.
 */
public class GWTController extends RemoteServiceServlet implements ServletConfigAware, ServletContextAware, Controller, RemoteService {

    private static final long serialVersionUID = 1L;

    protected ServletContext servletContext;

    @Override
    public ServletContext getServletContext() {
        return servletContext;
    }

    // Call GWT's RemoteService doPost() method and return null.
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // load our ServerContext with current request, response, session, user, appContext, etc.
        ServerContext.loadContext(request, response, servletContext);
        try {
            doPost(request, response);
        } finally {
            ServerContext.unloadContext();
        }
        return null; // response handled by GWT RPC over XmlHttpRequest
    }

    @Override
    public void setServletConfig(ServletConfig conf) {
        try {
            super.init(conf);
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    @Override
    protected void checkPermutationStrongName() throws SecurityException {
        return;
    }

    @Override
    protected void doUnexpectedFailure(Throwable e) {
        e.printStackTrace();
        super.doUnexpectedFailure(e);
    }

}

Upvotes: 2

Views: 1450

Answers (1)

axtavt
axtavt

Reputation: 242696

Security aspect provided by Spring Security inherits all limitations of Spring Framework proxy-based AOP support. In particular, aspects are not applied to calls that happen "inside" the objects (unless you use AspectJ weaving), see 7.6.1 Understanding AOP proxies.

So, if you want to use security aspect this way, you need to use GWT integration mechanism that make calls to your service from the outside, i.e. a mechanism that doesn't require your services to extend RemoteServiceServlet.

Something like spring4gwt should work fine.

Upvotes: 1

Related Questions