【问题标题】:Returning an error on invalid HttpSession Java Spring在无效的 HttpSession Java Spring 上返回错误
【发布时间】:2014-05-02 17:25:56
【问题描述】:

我目前正在运行一个使用 java Spring 处理会话的应用程序。我有以下代码,它为我处理所有会话。

    @RequestMapping(value = "/login", method = GET)
    public @ResponseBody
    UserCredentials startLoginProcess(HttpSession session)
    {
        //initiate session if none exists
    }

    @RequestMapping(value = "/login", method = POST)
    @ResponseStatus(value = HttpStatus.OK)
    public void login(@RequestBody UserCredentials user, HttpSession session)
    {
            //do login stuff
    }

  @RequestMapping(value = "/logout", method = GET)
  @ResponseStatus(value = HttpStatus.OK)
  public void logout(HttpSession session)
  {
    session.invalidate();
  }

这里的关键是调用invalidate() 的注销。这应该将会话标记为无效。 但是,当使用同一会话在无效后进行调用时,服务器会发送一个带有 200 OK 的响应和一个新的 set-cookie 标头。相反,我希望抛出一个错误,例如 403 或其他说明 cookie 现在无效的东西。 有什么方法可以做到这一点?

更具体一点,如果不存在新会话,我希望登录 GET 调用来处理创建新会话,但如果会话无效,所有其他调用都应该抛出某种类型的错误。显然HttpSession 上没有isInvalid 方法。

【问题讨论】:

  • 你的意思是说当用户调用logout 操作时你想验证会话是否有效如果有效你想继续logout 否则sessionExpired
  • 基本上,是的。长答案,如果会话无效,我希望在所有端点上都有一个sessionExpired,但 GET /login 除外
  • 通常会话检查可以在if(session==null)进行,如果那是空重定向到sessionExpired页面。
  • 那行不通,因为 spring 在会话到达我之前会自动将会话替换为有效会话。
  • 当用户调用 logout 操作时,您将会话分配为 null 并重定向到注销页面..

标签: java session spring-mvc spring-boot


【解决方案1】:

我将它用于我的 InvalidateController:

@Controller
@RequestMapping("/invalidate")
public class InvalidateController {

@RequestMapping(method = RequestMethod.GET)
public void showIndex(HttpServletResponse response) throws IOException {
    response.setStatus(299);
    response.getWriter().write("<script> window.location.href = '/login.jsp'</script>");
}
}

我所有的 javascript ajax (jQuery) 调用都会检查状态 299,如果会话超时,则重定向到登录页面。

据我了解,299 仍在成功调用的范围内 (200-299),但未使用,因此可以安全使用。

【讨论】:

  • 我不明白这是如何工作的......对我来说,当有人调用 GET /invalidate 时,他们总是会得到状态 299,当其他调用时,这如何在会话中返回错误作为 POST /login 被调用?
  • 您可以将状态更改为任何您想要的。要理解的关键点(我看我没有说清楚)是,当无效会话调用某些东西时,spring 会将请求转发到您在配置中设置的无效值。假设这是有效的,您将返回 200,因为重定向工作正常。技术上正确,但不是您所期望的。
  • 您能否指出我更改了​​此属性的位置?从技术上讲,我使用的是 spring boot,所以我没有配置文件。但如果你给我看一个示例配置,我可能会弄明白。
  • 我不知道spring boot,但是对于普通的spring,它在security-app-context.xml中,像这样: “invalidate” 然后映射到上面的控制器
  • 不幸的是,我对 spring security 或 spring boot 了解不够,无法弄清楚如何使用 spring boot。但感谢您到目前为止的帮助。
【解决方案2】:

这就是你需要的。当您将其标记为 sessionStatus.setComplete(); 时,spring 会为您删除所有内容。

@Controller
@RequestMapping(value = "/logout")
@SessionAttributes({"someSession"})
public class OutYouGo {
    @RequestMapping(method = RequestMethod.GET)
    public String logout(
         @ModelAttribute SomeSession someSession, 
         SessionStatus sessionStatus) {

        sessionStatus.setComplete();
        return SIGN_OFF_PAGE_LINK;
    }
}

【讨论】:

  • 这完全没有任何作用。
【解决方案3】:

我最终在没有任何配置的情况下解决了这个问题,只是不要求 Spring 给我一个会话。显然,spring 默认为您提供一个有效的会话,因为它调用request.getSession(true),如果一个不存在或无效,它会创建一个。 因此,我直接与false 要求进行会话。

  @RequestMapping(value = "/logout", method = GET)
  @ResponseStatus(value = HttpStatus.OK)
  public void logout(HttpServletRequest request)
  {
    HttpSession session = request.getSession(false);
    if (session != null) {
      session.invalidate();
    }
  }

然后在我的登录 GET 中,我仍然让它传入一个 HttpSession,但在我的登录 POST 中,我以与上面相同的方式获取会话。

【讨论】:

    猜你喜欢
    • 2019-02-22
    • 2021-01-06
    • 2020-04-29
    • 2020-12-22
    • 2011-10-06
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    相关资源
    最近更新 更多