在无效的HttpSession Java Spring上返回错误

在无效的HttpSession Java Spring上返回错误,java,session,spring-mvc,spring-boot,Java,Session,Spring Mvc,Spring Boot,我目前有一个应用程序正在运行,它使用JavaSpring来处理会话。我有以下代码,它为我处理所有会话 @RequestMapping(value = "/login", method = GET) public @ResponseBody UserCredentials startLoginProcess(HttpSession session) { //initiate session if none exists } @Req

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

    @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()
。这会将会话标记为无效。 但是,当使用同一会话在invalidate之后进行调用时,服务器将发送一个带有200ok和新set cookie头的响应。相反,我希望抛出一个错误,比如403或其他什么来声明cookie现在无效。 我有什么办法可以做到这一点


更具体地说,如果不存在新会话,我希望login GET调用处理创建新会话的问题,但是如果会话无效,所有其他调用都应该抛出某种类型的错误。显然,在
HttpSession

上没有
isInvalid
方法,我将其用于我的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>");
}
}
@控制器
@请求映射(“/invalidate”)
公共类无效控制器{
@RequestMapping(method=RequestMethod.GET)
public void showIndex(HttpServletResponse响应)引发IOException{
答复:setStatus(299);
response.getWriter().write(“window.location.href=”/login.jsp');
}
}
我所有的javascript ajax(jQuery)调用都会检查状态299,然后在会话超时时重定向到登录页面


据我所知,299仍在成功呼叫的范围内(200-299),但未使用,因此可以根据您的需要安全使用。

我将此用于我的InvalidateControl:

@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>");
}
}
@控制器
@请求映射(“/invalidate”)
公共类无效控制器{
@RequestMapping(method=RequestMethod.GET)
public void showIndex(HttpServletResponse响应)引发IOException{
答复:setStatus(299);
response.getWriter().write(“window.location.href=”/login.jsp');
}
}
我所有的javascript ajax(jQuery)调用都会检查状态299,然后在会话超时时重定向到登录页面


据我所知,299仍在成功呼叫的范围内(200-299),但未使用,因此可以根据需要安全使用。

这就是您所需要的。当您将其标记为
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;
    }
}

这就是你需要的。当您将其标记为
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;
    }
}

我最终在没有任何配置的情况下解决了这个问题,只是没有要求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();
    }
  }

然后,在我登录获取时,我仍然让它在HttpSession中通过,但在我的登录帖子中,我以与上面相同的方式获取会话。

我最终在没有任何配置的情况下解决了这个问题,只是没有要求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();
    }
  }


然后,在我登录时,我仍然在HttpSession中通过了它,但在我的登录帖子中,我获得了与上面相同的会话。

你的意思是说,当用户调用
注销
操作时,你想验证会话是否有效,如果你想继续
注销
否则
会话扩展
,基本上,对回答很长,如果会话无效,我希望在除GET/login之外的所有端点上都有一个
sessionExpired
。如果(session==null),则可以执行会话检查
如果为空,则重定向到
sessionExpired
页面。这不起作用,因为spring会在会话到达我面前自动将会话替换为有效会话。当用户调用
logout
操作时,您会将会话分配为空,并重定向到logout页面。您的意思是说当用户调用
logout
操作时,您想退出吗验证会话是否有效如果您想继续
注销
否则
sessionExpired
?基本上是的。回答很长,如果会话无效,我希望在除GET/login之外的所有端点上都有一个
sessionExpired
。如果(session==null),则可以执行会话检查
如果为空,则重定向到
sessionExpired
页面。这不起作用,因为spring会在会话到达我面前自动将会话替换为有效会话。当用户调用
logout
操作时,您将会话分配为空并重定向到注销页面。我不明白这是如何工作的。。。在我看来,当有人调用GET/invalidate时,他们总是会得到状态299,当调用其他调用(如POST/login)时,这如何在会话上返回错误?您可以将状态更改为您想要的任何状态。要理解的关键是(我看我没有说清楚)当无效会话调用某个内容时,spring会将请求转发到您在配置中设置invalidate的任何位置。假设这是可行的,你会得到一个200,因为重定向工作得很好。技术上是正确的,但不是你所期望的。你能告诉我这个属性在哪里被改变吗?从技术上讲,我使用的是spring boot,所以我没有配置文件。但是,如果你给我看一个配置示例,我可能会想出来。我不知道spring引导,但对于普通的spring,它在security-app-context.xml中,像这样:“invalidate”然后映射到上面的控制器。不幸的是,我对spring安全性或spring引导了解得不够,无法弄清楚如何使用spring引导实现这一点。但是谢谢你到目前为止的帮助。我不明白这是怎么回事。。。在我看来,当有人调用GET/invalidate时,他们总是会得到状态299,这如何在会话上返回错误