【问题标题】:Building a façade with spring which calls another server and returns its response使用 spring 构建一个外观,调用另一个服务器并返回其响应
【发布时间】:2015-06-11 13:24:05
【问题描述】:

对于一个应用程序,我需要在 Spring 4.x 中创建一个安全外观。

这个薄层必须接受来自我们的移动应用程序的任何请求,并对提供的令牌(使用 openId 和 Oauth)执行安全检查。

验证成功后,需要将请求转发到后端应用程序,后端应用程序不需要了解安全令牌机制。

因此,流程将是这样的: security_facade_url/path/of/the/request

带有一个标头,指示在成功验证令牌时要调用的后端

验证成功后,安全外观会向后端 URL 发送请求 backend_application_url/path/of/the/request

外观不得具有映射到请求的任何可能路径的控制器,但必须根据请求标头中的值在正确的后端服务器上调用请求。然后将此响应返回给用户。

到目前为止,我所拥有的是 HandlerInterceptor 的实现。这个拦截器有效,但是,我对通过在 postHandle 方法中抛出异常来避免 afterCompletion 的方式并不满意。 如果我没有抛出错误,默认错误页面会附加到 afterCompletion 步骤中的正确响应中。

这是我目前的代码:

public class RequestProcessingInterceptor implements HandlerInterceptor {    
private final Logger log = LoggerFactory.getLogger(RequestProcessingInterceptor.class);

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    log.info("Doing some security stuff now ...");

    log.warn("... security ok ... since I am not really checking stuff");
    return true;
}

public void postHandle(HttpServletRequest request,
                       HttpServletResponse response, Object handler,
                       ModelAndView modelAndView) throws Exception {
    log.info("Forwarding request and sending that info back ...");

    ClientConfig config = new DefaultClientConfig();
    Client client = Client.create(config);
    WebResource service = client.resource(UriBuilder.fromUri("http://localhost:8080").build());

    response.setContentType("application/json");
    response.getWriter().write(service.path(modelAndView.getModel().get("path").toString()).accept("application/json").get(String.class));
    response.setStatus(200);

    throw new Exception("Need to avoid the execution of the afterCompletion. Only way to do so is by throwing an exception...");
}

public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

}

}

是否有更合适的方法来干预 Spring 生命周期或获取上述行为?

【问题讨论】:

标签: spring rest interceptor facade


【解决方案1】:

找到了更好的解决方案。对于我所需要的,我不需要在拦截器中操作结果。

更简洁的方法是定义一个与请求方法映射的控制器。

@RequestMapping(method = {RequestMethod.GET, RequestMethod.PUT, RequestMethod.POST})
public void handleRequest(HttpServletRequest request, HttpServletResponse response) { // code omitted }

【讨论】:

    【解决方案2】:

    您不应试图回避对afterCompletion 的调用。只需实现一个空方法,让 SpringFramework 调用它。

    如果您的控制器返回 null 表示不必调用任何视图,它应该可以与更顺畅的 Spring 集成一起使用。

    但我不明白你为什么在这里使用 Spring MVC。由于您只与低级别的 HttpServletRequest 和 HttpServletResponse 交互,因此您也可以使用:

    • 一个专门的 servlet 负责将请求和响应中继到后端,并将返回值写入响应中
    • 在将请求传递给过滤器链之前会执行安全操作的过滤器

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 1970-01-01
      • 2014-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多