Java 如何关闭vaadin会话,但在浏览器关闭时保持http会话?

Java 如何关闭vaadin会话,但在浏览器关闭时保持http会话?,java,session,vaadin,httpsession,Java,Session,Vaadin,Httpsession,我正在使用jaas开发一个具有用户身份验证和授权的vaadin 7应用程序,jaas在应用程序服务器(glassfish)中定义了一个领域 我有以下要求: 用户可以保持登录一段时间,这样他就不必每次都输入密码。我通过设置http会话的会话超时来实现这一点 vaadin会话可以锁定某些资源,锁定时,其他会话不能使用此资源。关闭vaadin会话时,将释放所有锁定的资源。 我把心跳间隔设置为15秒 我无法同时满足这两个要求。 如果我将http会话超时设置为一分钟,则在关闭浏览器一分钟后释放资源,但

我正在使用jaas开发一个具有用户身份验证和授权的vaadin 7应用程序,jaas在应用程序服务器(glassfish)中定义了一个领域

我有以下要求:

  • 用户可以保持登录一段时间,这样他就不必每次都输入密码。
    我通过设置http会话的会话超时来实现这一点

  • vaadin会话可以锁定某些资源,锁定时,其他会话不能使用此资源。关闭vaadin会话时,将释放所有锁定的资源。
    我把心跳间隔设置为15秒

我无法同时满足这两个要求。 如果我将http会话超时设置为一分钟,则在关闭浏览器一分钟后释放资源,但下次用户未通过身份验证。
如果我将https会话超时时间设置为几天,则此时会对用户进行身份验证,但在错过3次心跳后,vaadin会话不会立即关闭。只有当用户下次使用相同http会话使用应用程序时,它才会关闭

如何实现这两个要求

以下是我正在使用的技术的更多信息:

  • 玻璃鱼4
  • 网络应用程序3.1
  • 瓦丁7.1.7
  • vaadin cdi 1.0-SNAPSHOT

谢谢您的帮助

您的问题有些含糊不清,但我相信您可以使用自己的close()方法来解决。您可以使用自定义close()方法创建自己的Vaadin应用程序类,或者使用TPTApplication并重写其close()方法:

确保在会话关闭时调用close,并在那里进行清理。在会话结束时也将调用该函数

如果您不能确保这一点(即,如果用户只是关闭窗口,而您没有一些javascript来处理这一点),您可以使用Vaadin拦截窗口关闭,但这需要做更多的工作。当用户试图关闭窗口时,您会中断该过程,通过回调执行需要执行的操作,然后让关闭发生。有关如何从vaadin中断的详细信息如下所示:

https://vaadin.com/forum/#!/thread/44621/44668
https://vaadin.com/forum/#!/thread/83207/83206
回调仅限于客户端,因此您必须调用服务器(通过javascript获取/发布),该服务器将会话id传递给您正在侦听的servlet。然后servlet将使用传入的会话id释放锁


关键是监听窗口是否关闭,并能够对其做出适当的响应。

您可能想看一看,尤其是-我个人会使用另一种方法,而不是自己尝试实现安全的持久登录

如果你想走DIY之路:

我认为尝试将Vaadin与Http会话分离并不是一个好主意。报告说:

当一个新客户端连接时,它会创建一个新的用户会话,由一个VaadinSession实例表示。使用浏览器中存储的Cookie跟踪会话…[Vaadin会话]还通过WrappedSession提供对低级会话对象HttpSession和PortletSession的访问

也许您可以将第一个需求(“用户可以保持登录一段时间,这样他就不必每次都输入密码”)的解决方案更改为将登录凭据与http会话分离


您可以将一些带时间戳的唯一id存储为cookie(带有过期日期),并使用自己的
SessionInitListener
SessionDestroyListener
检查(并设置)并且根据您在服务器上所做的检查,需要登录凭据或接受客户端的凭据。

您能否澄清必须释放哪种类型的锁定资源?或者你是指一般的资源?在我的例子中,资源是数据库中的一些条目。我用的是我自己的锁定装置。但关键问题实际上是如何在浏览器关闭后关闭vaadin会话而不使http会话无效。我现在的解决方法是只释放锁定的db条目,但保留vaadin sesion。我有一个计时器,每分钟检查心跳是否仍然收到。谢谢你考虑我的问题,但我认为这不是解决我问题的办法。重写UI.close()(我使用的是vaadin 7)函数已经完成,但没有调用它,因为如果http会话没有超时,则不会关闭vaadin会话。可以用javascript捕获浏览器关闭事件,但不能保证它在所有情况下都能工作(例如浏览器崩溃)。我想从计时器线程或其他会话关闭一个Vaadin会话,但保留http会话属于已关闭的Vaadin会话。谢谢您的回答。记住,用户身份验证并不是一个真正的问题。可以使用Spring Security或我自己的带有令牌的cookie。这将使身份验证与http会话分离。但我也在使用授权(@RolesAllowed annotation),这就是我问题的难点所在。当然,我也可以使用另一个框架进行授权,但我真的不想这样做。当用户打开应用程序进行自动登录时,您不能使用身份验证信息吗。因此,不需要更改授权代码中的任何内容。还是我没有领会你的意思?在第一次登录时,我使用用户名和密码进行编程登录(HttpServletRequest.login())。只要http会话存在,就可以进行授权。如果我使用令牌来记住用户,我将不得不基于该令牌进行登录。我不知道怎么做。或者我可以在应用程序的某个地方记住密码,但我不喜欢这个想法。所以保持http会话一段时间对我来说似乎是最好的主意,但我想关闭vaadin会话
https://vaadin.com/forum/#!/thread/44621/44668
https://vaadin.com/forum/#!/thread/83207/83206