我编写了一个 HTML 5 应用程序,它使用 AngularJS 并与在 Tomcat 上运行的 Java REST 后端进行交互。
我使用 Spring Security 来处理登录和安全性。
当用户进入网站时,他将被转发到登录页面,该页面创建会话并重定向到索引页面。 REST 调用从服务器加载更多数据,然后使用该会话进行身份验证。
如果没有适当的会话,我会回退到通过 HTTP 进行基本身份验证,这样就可以与 Web 应用程序分开调用 REST 端点。
我现在遇到的问题是会话何时过期。这会导致HTTP 401 Unauthenticated
来自服务器的响应。我想我可以捕获该错误并使用 JavaScript 将用户重定向回登录页面。然而,在调用我的错误处理程序之前,浏览器首先显示一个登录窗口,只有当我单击“取消”时,我的 Javascript 错误处理程序才能处理响应。
我的问题是,有没有办法阻止浏览器显示此登录窗口?或者这是我的应用程序设计的普遍问题?
另一种选择可能是根本不使用会话并在应用程序中缓存用户名和密码。然后我需要使用基本身份验证在每个 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
Update:看来,造成这种情况的原因是WWW-Authenticate
header,这会导致浏览器显示登录对话框。
我终于找到了这个问题的解决方案。正如我在更新中提到的原因是,响应包含WWW-Authenticate
标头字段。我的解决方案是更改 spring security 的配置以返回不同的标头:
WWW-Authenticate: FormBased
为此,我必须实施AuthenticaitonEntryPoint
接口并手动设置响应中的标头和状态代码:
@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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)