我正在尝试将基于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内部工作?
答案 0 :(得分: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)
}
}
结果是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)
}
}