【问题标题】:Spring 3.2 REST API add cookie to the response outside controllerSpring 3.2 REST API 将 cookie 添加到控制器外部的响应中
【发布时间】:2014-07-30 16:26:22
【问题描述】:

我正在使用 Spring 3.2.4 和 Spring Security 3.2.3 来处理 RESTful API 调用以“获取安全令牌”请求返回令牌(这将用于保护对服务的后续请求)。这是一个 POST 请求,其主体包含用户名和密码,并在控制器中处理:

@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public SessionTokenResponse getSessionToken(@RequestBody Credentials credentials, ModelAndView interceptorModel) throws AccessException {
    final String token = webGate.getSessionTokenForUser(credentials.getUsername(), credentials.getPassword());
    LOGGER.debug("Logged in user : " + credentials.getUsername());

    interceptorModel.addObject(SessionConstants.INTERCEPTOR_MODEL_TOKEN_KEY, token); // Used by post-processing in interceptors, e.g. add Cookie

    return new SessionTokenResponse(ResponseMessages.SUCCESS, token);
}

控制器成功处理完请求后,我想在响应中添加一个带有令牌的 cookie。 我尝试了 HandlerInterceptorAdapter 实现,但我无法从响应或 ModelAndView 中找到通往“令牌”的方法:

    @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView interceptorModel) throws Exception {
    final String token = (String) interceptorModel.getModel().get(SessionConstants.INTERCEPTOR_MODEL_TOKEN_KEY);

    if (token != null) {
        final Cookie obsso = new Cookie(cookieName, token);
        obsso.setPath(cookiePathUri);
        obsso.setDomain(cookieDomain);
        obsso.setMaxAge(cookieMaxAge);

        response.addCookie(obsso);
    }
}

interceptorModel 是 null 。 似乎 Spring MVC 没有将它提供给 postHandle,因为 @ResponseBody 已经被解析并且不再需要 ModelAndView (这只是我基于调试的假设)。

在拦截器或侦听器的控制器之外实现这一点(将 cookie 添加到响应中)的正确方法是什么?

【问题讨论】:

  • 也因为你扩展HandlerInterceptorAdapter postHandle 方法将只有请求,响应和对象参数。不幸的是,您不能为 Spring 添加另一个参数来填充。但我似乎记得找到了一种从HttpServletRequestHttpServletResponse 对象中获取ModelAndView 对象的方法。我只是不记得是怎么回事。

标签: spring rest spring-mvc spring-security interceptor


【解决方案1】:

要检索令牌,您可以使用请求对象

 request.setAttribute(SessionConstants.INTERCEPTOR_MODEL_TOKEN_KEY, token);

然后在postHandle中

 String token = ( String ) request.getAttribute(SessionConstants.INTERCEPTOR_MODEL_TOKEN_KEY);

但是我认为您不能在 postHandle 中向响应对象添加 cookie,因为响应已经提交。

也许您可以将令牌信息存储在 servlet 上下文中。

在您的控制器中,将令牌信息添加到 servlet 上下文。
然后实现 preHandle,以便每个 api 调用都可以检查该用户的令牌是否存在于 servlet 上下文中,如果存在,您可以将 cookie 添加到响应中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-12
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 2022-12-05
    • 2017-12-04
    • 1970-01-01
    相关资源
    最近更新 更多