我遇到了我以前见过的最奇怪的问题。
我正在开发的应用程序使用 spring security 3.1.3 来提供身份验证支持。有一个自定义登录表单,我为其实现了自定义身份验证管理器/成功处理程序和失败处理程序。
出于某种原因,在 Internet Explorer 上,我总是收到错误消息“请填写所有必填字段”。这是由于将 /login?error=1 附加到我的 url 的末尾,只能通过以下代码(redirectAndAddError 方法)访问该 URL:
public class TideUserNamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
public TideUserNamePasswordAuthenticationFilter() {
super();
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
String username = request.getParameter(SPRING_SECURITY_FORM_USERNAME_KEY);
String password = request.getParameter(SPRING_SECURITY_FORM_PASSWORD_KEY);
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
redirectAndAddError(response);
return null;
}
return super.attemptAuthentication(request, response);
}
private void redirectAndAddError(HttpServletResponse response) {
try {
response.sendRedirect("/tide/login?error=1");
} catch (IOException e) {
throw new AuthenticationServiceException(e.getMessage(), e);
}
}
所以我尝试使用 Fiddler2,一个 Web 调试代理来查看两个参数之一是否实际上为空。奇怪的是,当这个程序运行时,错误不再发生,我可以成功登录。
以前有没有人遇到过类似的问题?我认为这与我的代码无关,因为运行该工具突然“解决”了问题。
这个问题只发生在 Internet Explorer 中,这使得它更加奇怪。
编辑
我使用了另一个工具来查看请求,这就是 IE 中发生的情况:
首先一个 POST 请求被发送到 uri /authenticate,我自己设置了这个:
<beans:property name="filterProcessesUrl" value="/authenticate"/>
该请求的响应具有 http 状态代码 302,临时移动并返回新位置位于 /login?error=1 (我的表单带有必填字段需要错误)。
之后,向 /login?error=1 发出 GET 请求,状态码为 401:未授权。拦截 URL 设置如下:
<intercept-url pattern="/login**" access="permitAll"/>
下一个请求是对 /login?error=1 的 GET 请求,这次状态码显示:ERROR_INTERNET_CONNECTION_RESET,看起来可能是个问题。
在 Google Chrome 中,发出以下请求:
POST 到 /authenticate,结果是 302: 临时移动到仪表板页面(我在登录后显示)