0

Using Spring (4.2.4) with MVC (4.2.4) and Security (4.0.3). I have implemented an AccessDecisionManager and from within my decide-method I am throwing an exception:

public void decide(
    Authentication authentication, 
    Object object,
    Collection<ConfigAttribute> configAttributes
)   throws AccessDeniedException, InsufficientAuthenticationException {
        FilterInvocation fi = (FilterInvocation) object;
        String requestUrl = fi.getRequestUrl();
    ...
    throw new SessionCompanyNotRoleTableCompanyException(1, 2);
    ...
    throw new AccessDeniedException("Access denied!");
}

I'm not able to catch neither "SessionCompanyNotRoleTableCompanyException" nor AccessDeniedException. I've tried using a global exception handler:

@Component
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

@ExceptionHandler(SessionCompanyNotRoleTableCompanyException.class)
public ModelAndView sessionCompanyNotRoleTableCompany() {
    log.debug("SessionCompanyNotRoleTableCompanyException captured in GlobalExceptionHandler");
    String reason = "Reason: SessionCompanyNotRoleTableCompanyException";
    ModelAndView mav = new ModelAndView();
    mav.addObject("reason", reason);
    mav.setViewName("error.html");
    return mav;             
}

@ExceptionHandler(Exception.class)
public ModelAndView exception(ModelMap model) {
    log.debug("Exception captured in GlobalExceptionHandler");
    String reason = "General Exception";
    ModelAndView mav = new ModelAndView();
    mav.addObject("reason", reason);
    mav.setViewName("error.html");
    return mav;             
}
}

I've even created ExceptionResolver-classes like:

@Component
public class SessionCompanyNotRoleTableCompanyExceptionResolver implements HandlerExceptionResolver, Ordered {

    private static final Logger log = LoggerFactory.getLogger(SessionCompanyNotRoleTableCompanyExceptionResolver.class);

    private int order;

    @Override
    public ModelAndView resolveException(
        HttpServletRequest request, 
        HttpServletResponse response, 
        Object handler,
        Exception ex
    ) {
        if (ex instanceof SessionCompanyNotRoleTableCompanyException) {
            log.debug("SessionCompanyNotRoleTableCompanyException captured in SessionCompanyNotRoleTableCompanyExceptionResolver");
            String reason = "Reason: SessionCompanyNotRoleTableCompanyException";
            ModelAndView mav = new ModelAndView();
            mav.addObject("reason", reason);
            mav.setViewName("error.html");
            return mav;             
        }
        return null;
    }

    @Override
    public int getOrder() {
        return order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

}

... and have them initialized in my web-config-class like:

@Bean
public SessionCompanyNotRoleTableCompanyExceptionResolver createSessionCompanyNotRoleTableCompanyExceptionResolver() {
    SessionCompanyNotRoleTableCompanyExceptionResolver resolver = new SessionCompanyNotRoleTableCompanyExceptionResolver();
    resolver.setOrder(1);
    return resolver;
}

These work, i.e. exceptions are captured ONLY IF they are thrown from the Controllers. But NOT from my decide-method in the AccessDecisionManager.

What and how am I supposed to implement something that can catch these outside (before) the controller?

EDIT (adding the SessionCompanyNotRoleTableCompanyException to show you its definition):

public class SessionCompanyNotRoleTableCompanyException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public SessionCompanyNotRoleTableCompanyException(Long contextCompanyId, Long tableId) {
        super("Context companyId: " + contextCompanyId + ", tableId: " + tableId);
    }

}
  • Don't use `@Component` annotation if you're going to declare bean in configuration manually with `@Bean` annotation. Otherwise, your bean will be created twice. Once by package scan, and once by configuration. Try to set order of your `SessionCompanyNotRoleTableCompanyExceptionResolver ` to `0` or even to `-1`. Possible any handlers stay before it. – Ken Bekov Mar 18 '16 at 08:16
  • Thanks @KenBekov. Removing `@Component` but keeping order=1 in `SessionCompanyNotRoleTableCompanyExceptionResolver` didn't work. But when I set the order=-1, it got captured when thrown from the Controller-class. BUT, when I try to call a page (by setting it up so that the exception would get triggered in `decide`-method in `AccessDecisionManager`, i.e. BEFORE the controller is hit) it still doesn't work. I get a general Tomcat-page displaying the exception :( I editted the post by adding the SessionCompanyBlaBla-exception definition. – Salman P. Dar Mar 18 '16 at 09:17

0 Answers0