我正在使用 Grails 1.3.7 和最新的 spring-security-core 插件。我在我的 LoginController 中实现了以下方法:

def authAjax = {
   response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl
   response.sendError HttpServletResponse.SC_UNAUTHORIZED
}

在我的全局 JavaScript 文件中,我有以下内容:
$.ajaxSetup({
   error: function(xhr, status, err) {
      if (xhr.status == 401) {
         // display a login form in a dialog
      }
   }
});

登录表单是直接来自插件文档的标准登录表单。唯一的区别是我使用 jQuery 提交表单,如下所示:
var params = $('#ajaxLoginForm').serialize();
$.post($('#ajaxLoginForm').attr('action'), params, function(jsonData) {
   if (jsonData.success) {
      $('#login-dialog').dialog('close');
   } else {
      alert('TODO: display errors');
   }
}, 'json');

问题是我第一次单击登录按钮时,我似乎可以进行身份​​验证,但是从服务器返回的响应是基于 Referer 请求 header 的 302 重定向。所以我的 $.post() 的正文永远不会运行。我正在返回 HTML 而不是 JSON。在第二次提交之前,它实际上并没有命中我的 LoginController.ajaxSuccess 方法。我已经阅读并重新阅读了文档,我一定遗漏了一些东西。

更新:看起来它可能不是 Referer 问题,因为第二次发布表单后,Referer 仍然存在。所以我完全不知道为什么我必须两次提交表单才能调用 ajaxSuccess 方法。

最佳答案

当您未经授权尝试访问 protected 资源时,Spring Security 会将该请求保存在您的 session 中 (http://static.springsource.org/spring-security/site/apidocs/org/springframework/security/web/savedrequest/DefaultSavedRequest.html),然后当您成功进行身份验证时,它会将您重定向到该请求。您可能可以使用 Spring Security 配置全面关闭此行为,但这对于大多数工作流程来说可能不是您想要的。您也可以在 authAjax 方法中从 session 中显式删除 SavedRequest,但同样,这可能不是用户的最佳体验。

我相信 LoginController.ajaxSuccess 只有在没有 SavedRequest 重定向到 insted 时才会被命中,因此您返回的 HTML 应该是您原始请求的结果,当时该请求未经授权。因此,诀窍是您想使用任何用于处理原始请求的函数作为#ajaxLoginForm 提交的成功方法。

关于jquery - Spring Security Core authAjax,如何忽略Referer,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5628199/

10-11 20:19
查看更多