http - 在过期 session : HTTP 401 response causes browser to display login window 上休息调用

标签 http rest session spring-security session-timeout

我编写了一个 HTML 5 应用程序,它使用 AngularJS 并与在 Tomcat 上运行的 Java REST 后端接口(interface)。 我使用 Spring Security 来处理登录和安全性。

当用户进入网站时,他被转发到一个登录页面,该页面创建一个 session 并重定向到索引页面。 REST 调用从服务器加载更多数据,然后使用该 session 进行身份验证。 如果没有适当的 session ,我会回退到通过 HTTP 的基本身份验证,这样就可以从 Web 应用程序中单独调用 REST 端点。

我现在遇到的问题是 session 何时过期。这会导致来自服务器的 HTTP 401 Unauthenticated 响应。我以为我可以捕获该错误并使用 Javascript 将用户重定向回登录页面。然而,在我的错误处理程序被调用之前,浏览器首先显示一个登录窗口,只有当我点击取消时,我的 Javascript 错误处理程序才能处理响应。

我的问题是,有没有办法阻止浏览器显示这个登录窗口?或者这是我的应用程序设计的普遍问题?

替代方案可能是根本不使用 session 并在应用程序中缓存用户名和密码。然后我需要使用基本身份验证在每次 REST 调用时发送它,这是更好的方法吗?

以下是来自服务器的 HTTP 响应:

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
WWW-Authenticate: Basic realm="Spring Security Application"
Content-Type: text/html;charset=utf-8
Content-Length: 999
Date: Mon, 30 Sep 2013 11:00:34 GMT

更新:看来这是因为 WWW-Authenticate header 导致浏览器显示登录对话框。

最佳答案

我终于找到了解决方案。正如我在更新中提到的,原因是响应包含 WWW-Authenticate header 字段。然后我的解决方案是更改 spring security 的配置以返回不同的 header :

WWW-Authenticate: FormBased

为此,我必须实现 AuthenticaitonEntryPoint 接口(interface)并在响应中手动设置 header 和状态代码:

@Component( "restAuthenticationEntryPoint" )
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence( HttpServletRequest request, HttpServletResponse response,
                          AuthenticationException authException ) throws IOException {
        response.setHeader("WWW-Authenticate", "FormBased");
        response.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
    }
}

然后我更改了 spring-security 的配置并将 entry-point-ref 设置为指向新类:

<http pattern="/rest/**" create-session="never" entry-point-ref="restAuthenticationEntryPoint">
    <intercept-url pattern="/rest/**" access="ROLE_USER" />
    <http-basic />
    <session-management />
</http>

关于http - 在过期 session : HTTP 401 response causes browser to display login window 上休息调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19079687/

相关文章:

javascript - 重定向到包含原始帖子数据的 URL

android - 是否可以从同一网络上的另一台设备访问部署在 Android 手机上的 HTTP 服务器?

python - 地理编码库

rest - 带有 F# 的 Kraken 私有(private) API 返回 EGeneral : invalid arguments

ruby-on-rails - 如何在不登录的情况下将 "Like"功能添加到我的博客文章中

javascript - 如何在 Symfony 中将 PHP session 变量传递给外部 JS 文件

jquery - Symfony、jQuery.ajax() 调用、 session 变量丢失

http - 静态内容的 http header 中的 "Expires"?如何

java - 将访问权限存储在数据库表中是常见的做法吗?

http - 如何判断 HTTP 响应是否在 C 中终止