我如何绕过Grails异常处理才能使用Spring Oauth2?

时间:2012-06-29 12:37:17

标签: spring grails spring-security oauth-2.0

我正在尝试将基于Oauth for Spring Security的Oauth2客户端从普通的Java / Spring移植到Grails,并且遇到了问题。问题的关键似乎是Spring Oauth客户端实现的设计依赖于以下假设:Oauth2RestTemplate抛出的异常将被捕获到OAuth2ClientContextFilter的catch块中,从而允许过滤器发出重定向响应(向誓言提供者发送授权请求)。

这在普通Java / Spring中运行良好,但在Grails中,GrailsDispatcherServlet配置为通过HandlerExceptionResolvers处理所有异常。因此,在GrailsExceptionResolver中捕获Oauth2RestTemplate(在Grails控制器内部调用)中抛出的异常,OAuth2ClientContextFilter永远不会看到它,从而破坏了所需的重定向行为。

我发现自定义Grails异常处理的所有讨论似乎都假设自定义的目的是将异常映射到HTTP错误代码或错误页面视图。但有没有办法告诉Grails只允许特定的异常流经未处理的,以便它可以被servlet过滤器捕获?或者是否可以插入一个自定义的HandlerExceptionResolver来重新抛出异常而不是返回一个ModelAndView(这是HandlerExceptionResolver的标准期望)?或者是否有其他更好的方法可以让Spring安全客户端的Oauth在Grails内部工作?

2 个答案:

答案 0 :(得分:1)

这是我最终想出来的。不确定它是否是最佳解决方案,但似乎有效:

  1. 创建一个新的MyDispatcherServlet.groovy:

    package org.example.com
    
    import org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet
    import javax.servlet.http.HttpServletRequest
    import javax.servlet.http.HttpServletResponse
    import org.springframework.web.servlet.ModelAndView
    import org.springframework.security.oauth2.client.UserRedirectRequiredException
    
    class MyDispatcherServlet extends GrailsDispatcherServlet {
    
        @Override
        protected ModelAndView processHandlerException(HttpServletRequest request, 
          HttpServletResponse response, Object handler, Exception ex) throws Exception {
            def e = ex
            while (e) {
                if (e instanceof UserRedirectRequiredException) {
                    throw ex
                }
                e = e.cause
             }
             return super.processHandlerException(request, response, handler, ex)                                     
         }
    }
    
  2. 运行 grails install-templates 并修改web.xml以使用MyDispatcherServlet而不是默认的GrailsDispatcherServlet
  3. 结果是MyDispatcherServlet将重新抛出一个包含UserRedirectRequiredException的异常,以便它可以被OAuth2ClientContextFilter捕获,但其他异常将像以前一样由GrailsExceptionResolver传递和处理。

答案 1 :(得分:1)

我认为您可以通过定义自定义异常解析程序在exceptionHandler中声明resources.groovy。此自定义异常解析程序可以(可选)覆盖GrailsExceptionResolver

exceptionHandler(MyExceptionResolver) {
    exceptionMappings = ['java.lang.Exception': '/error']
}

class MyExceptionResolver extends GrailsExceptionResolver {
     @Override
     ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, 
      Object    handler, Exception ex) {
     //your custom code
     return super.resolveException(request, response, handler, ex)
    }
}