Jquery SpringSecurityCoreAuthAjax,如何忽略Referer

Jquery SpringSecurityCoreAuthAjax,如何忽略Referer,jquery,ajax,authentication,grails,spring-security,Jquery,Ajax,Authentication,Grails,Spring Security,我正在使用Grails1.3.7和最新的SpringSecurity核心插件。我在LoginController中实现了以下方法: def authAjax = { response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl response.sendError HttpServletResponse.SC_UNAUTHORIZED } 在我的全局JavaScript

我正在使用Grails1.3.7和最新的SpringSecurity核心插件。我在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');
问题是,第一次单击login按钮时,我似乎正在验证ok,但从服务器返回的响应是基于Referer请求头的302重定向。因此,我的$.post()的主体永远不会运行。我得到的是HTML而不是JSON。直到第二次提交时,它才真正击中我的LoginController.ajaxSuccess方法。我读了又读了一遍文档,一定是遗漏了什么


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

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


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

Gregg,您可能遇到了401响应的默认servlet容器行为。我建议您使用以下方法:

def authAjax = {
    response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl
    render status: 401, contentType: "application/json", {
    message = "You are not authorized for this page"
    }
}

我还没有测试过它,所以让我知道它是如何运行的。

Micah,谢谢你的回答。在大多数情况下,我相信你是正确的。但是,spring security core文档中没有关于这一点的内容,在两个屏幕广播中也没有提到这一点,特别是第二个屏幕广播,它涵盖了这个确切的场景。因此,必须有一个bug或我遗漏的东西,或者我认为教程没有明确说明的东西。我将把这个答案标记为正确的,除非有人提供一个黑客较少的解决方案。基本上,在authAjax方法中,我做了以下操作:session.SPRING\u SECURITY\u SAVED\u REQUEST\u KEY=null。现在它按预期工作。嗨,我面临一个类似的issue,当会话终止时,如果我单击终止会话屏幕内的任何链接,authAjax将发送401错误,而我需要将用户转发到登录屏幕,您是如何实现的?我尝试了黑客攻击,我需要添加全局js重定向吗?authAjax中的最终内容是什么,不会改变我所体验的行为当我看到来自authAjax的Firebug中的响应时,我没有看到json。我确实看到contentType设置正确,但消息从未出现。