Spring:从AccessDecisionManager抛出异常 - 不是来自Controller

时间:2016-03-18 07:16:11

标签: spring security model-view-controller handlerexceptionresolver

将Spring(4.2.4)与MVC(4.2.4)和安全性(4.0.3)一起使用。我已经实现了一个AccessDecisionManager,并且从我的决定方法中我抛出一个异常:

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!");
}

我既不能抓住“SessionCompanyNotRoleTableCompanyException”也不能抓住AccessDeniedException。我尝试过使用全局异常处理程序:

@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;             
}
}

我甚至创建了ExceptionResolver类,如:

@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;
    }

}

...并在我的web-config-class中初始化它们,如:

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

这些工作,即只有在从控制器抛出异常时才会捕获异常。但不是decide中的AccessDecisionManager - 方法。

我应该实现什么以及如何实现可以在控制器之外(之前)捕获这些内容的东西?

编辑(添加SessionCompanyNotRoleTableCompanyException以显示其定义):

public class SessionCompanyNotRoleTableCompanyException extends RuntimeException {

    private static final long serialVersionUID = 1L;

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

}

0 个答案:

没有答案