【问题标题】:Spring Security Core authAjax, How do I ignore the RefererSpring Security Core authAjax,我如何忽略Referer
【发布时间】:2011-08-03 10:43:43
【问题描述】:

我正在使用 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请求标头的302重定向。所以我的 $.post() 的主体永远不会被运行。我得到的是 HTML 而不是 JSON。在第二次提交之前,它实际上并没有命中我的 LoginController.ajaxSuccess 方法。我已经阅读并重新阅读了文档,但我一定遗漏了一些东西。

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

【问题讨论】:

    标签: jquery ajax authentication grails spring-security


    【解决方案1】:

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

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

    【讨论】:

    • Micah,谢谢你的回答。在大多数情况下,我相信你是对的。但是,在 spring-security-core 文档中没有任何内容,也没有在 2 个截屏视频中提及,特别是涵盖此确切场景的第二个截屏视频。所以要么有错误,要么我遗漏了什么,或者我认为教程没有明确说明。
    • 我会将此答案标记为正确,除非有人提出了一个较少被黑客入侵的解决方案。基本上,在 authAjax 方法中,我执行了以下操作: session.SPRING_SECURITY_SAVED_REQUEST_KEY = null。现在它按预期工作。
    • 您好我遇到了类似的问题,当会话终止时,如果我单击终止会话屏幕中的任何链接,authAjax 会发送 401 错误,而是我需要将用户转发到登录屏幕,怎么做你实现了这个?我尝试了hack,是否需要添加全局js重定向?
    • 还有什么是authAjax的最终内容
    【解决方案2】:

    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"
        }
    }
    

    我还没有测试过,所以让我知道它是怎么回事。

    【讨论】:

    • 这并没有改变我正在经历的行为。当我查看来自 authAjax 的 Firebug 响应时,我没有看到 json。我确实看到 contentType 设置正确,但消息从未出现过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    • 2014-10-05
    • 2018-06-21
    • 2016-08-15
    • 2018-08-12
    • 2022-01-25
    • 2014-03-11
    相关资源
    最近更新 更多