Spring Security 3 Ajax登录–访问受保护的资源

我看过一些有关Spring Security 3 Ajax登录的博客,但是我找不到解决如何调用基于Ajax的登录的博客,匿名用户正在Ajax中访问受保护的资源。

问题 – Web应用程序允许匿名访问某些部分,并且某些部分是受保护的资源,需要用户登录。

当匿名用户(通过Http Get / Post)访问受保护的资源时,Spring Security会自动调用登录页面,并在成功通过身份验证后重定向到所需的资源/页面。

但是,如果正在Ajax中访问受保护的资源,则登录页面将无法正确显示(将在页面的一部分上进行设置)。 302代码(重定向到登录页面)将无法在Ajax中正常运行。

请注意,这与启动Ajax登录屏幕不同(例如,当用户按下登录按钮并调用带有用户/密码字段的弹出窗口时)。

那么–我们如何让Spring Security 3通过“常规” HTTP Post(基于FORM的身份验证)和Ajax调用来处理对受保护资源的访问,包括在成功身份验证后重定向到所需资源?

因此,此博客文章包含两个保护层/部分:
1. Spring Security 3标准基于FORM的身份验证
2.配置/扩展Spring Security 3.并且该应用程序还支持Ajax对受保护资源的访问。

关于第1部分-有关此问题的参考很多。 无需详细说明。

关于第2部分–要求以下内容:

1.配置Spring Security 3以启用基于Ajax的登录。
2.将客户端Ajax调用配置为受保护的资源,以处理身份验证请求。
3.重新执行功能以模拟成功登录后自动进行用户原始方法的调用(这在基于FORM的登录中发生)

下图描述了详细的流程,应有助于遵循客户端/服务器通信。

通过Ajax处理受保护的资源访问

让我们讨论一下图:

该流程始于对受保护资源(1)的匿名用户Ajax请求。 在这种情况下,用户希望将商品添加到购物车。

addItem方法是受保护的资源,它通过Spring Security(@pre_authorize(“ SOME_ROLE”))(2)受保护。 这使Spring Secutiry过滤器(3)发送带有HTTP代码302的登录表单(即,重定向到该页面)。

现在,由于这是一个Ajax调用,它将无法很好地处理请求,因此这里涉及到了登录表单,将其放在一边,然后调用基于Ajax的登录(4):

客户端Ajax方法(调用了Ajax addItem方法)检查​​它是基于表单的登录名还是其他任何答复。 如果是基于FORM的登录,它将调用一个对话框模式(5),该模式将尝试登录Ajax。 Spring将处理Ajax登录认证(6)并将适当的消息返回给客户端。 如果消息成功,则客户端将重新执行原始功能,该功能试图访问受保护的资源(例如,本例中的addItem )。

让我们看看它们如何适合我们的代码:
步骤#1,#4 –客户端访问受保护的资源并检查是否需要登录

//JavaScript method - Ajax call to protected resource (#1 in flow diagram)
function addItem(itemId) {    $.ajax({url: '/my_url/order/addItem',type: 'POST',data: ({orderItemId : itemId,...}),               success: function(data) {//construct a callback string if user is not logged in.var cllbck = 'addItem('+itemId +')';//Client check if login required//(#4 in flow diagram)if (verifyAuthentication(data,cllbck)){// in here => access to protected resource was ok// show message to user, "item has been added..."}});}

步骤#2,#3 –是常规的Spring Security配置。 的大量资源 了 那里 。

步骤#4 –客户端检查是否需要登录:

function verifyAuthentication(data, cllBackString){//naive check - I put a string in the login form, so I check for existanceif (isNaN(data) && (data.indexOf("login_hidden_for_ajax")!= -1)){//if got here then data is a loginform => login required//set callback in ajax login form hidden input  $("#my_callback").val(cllBackString); //show ajax login//Get the window height and widthvar winH = $(window).height();var winW = $(window).width();//Set the popup window to center$("#ajaxLogin").css('top',  winH/2-$("#ajaxLogin").height()/2);$("#ajaxLogin").css('left', winW/2-$("#ajaxLogin").width()/2);$("#ajaxLogin").fadeIn(2000); return false;} // data is not a login form => return true to continue with function processingreturn true; 
}

步骤#5,#7 – Ajax登录表单使用以下Ajax登录:

function ajaxLogin(form, suffix){var my_callback = form.my_callback.value; // The original function which accessed the protected resourcevar user_pass = form.j_ajax_password.value;var user_name = form.j_ajax_username.value; //Ajax login - we send credentials to j_spring_security_check (as in form based login$.ajax({url: "/myContextURL/j_spring_security_check",    data: { j_username: user_name , j_password: user_pass }, type: "POST",beforeSend: function (xhr) {xhr.setRequestHeader("X-Ajax-call", "true");},success: function(result) {     //if login is success, hide the login modal and//re-execute the function which called the protected resource//(#7 in the diagram flow)if (result == "ok") {$("#ajax_login_error_"+ suffix).html("");            $('#ajaxLogin').hide();if (my_callback!=null && my_callback!='undefined' && my_callback!=''){eval(my_callback.replace(/_/g,'"'));}return true;}else {        $("#ajax_login_error_"+ suffix).html('<span  class="alert display_b clear_b centeralign">Bad user/password</span>') ;return false;         }},error: function(XMLHttpRequest, textStatus, errorThrown){$("#ajax_login_error_"+ suffix).html("Bad user/password") ;return false; }
});
}

我们需要将Spring设置为支持Ajax登录(#6):

设置Spring Security xml配置:

<beans:beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/security" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd"><http auto-config="false" use-expressions="true"><intercept-url access="hasRole('ROLE_ADMIN')" pattern="/admin**"><intercept-url filters="none" pattern="/**"><intercept-url access="permitAll" pattern="/signin/**"><form-login authentication-failure-handler-ref="ajaxAuthenticationFailureHandler" authentication-success-handler-ref="ajaxAuthenticationSuccessHandler" login-page="/common/authentication/login"> <logout invalidate-session="true" logout-success-url="/common/authentication/logout"><custom-filter before="LOGOUT_FILTER" ref="logoutFilter"></custom-filter></logout></form-login></intercept-url></intercept-url></intercept-url></http>...
</beans:beans>

定义成功登录的处理程序:

@Component("ajaxAuthenticationSuccessHandler")
public class AjaxAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { public AjaxAuthenticationSuccessHandler() {    }@Overridepublic void onAuthenticationSuccess(HttpServletRequest request,HttpServletResponse response, Authentication authentication)throws IOException, ServletException { HttpSession session = request.getSession();  DefaultSavedRequest defaultSavedRequest = (DefaultSavedRequest) session.getAttribute(WebAttributes.SAVED_REQUEST);//check if login is originated from ajax callif ("true".equals(request.getHeader("X-Ajax-call"))) {try {response.getWriter().print("ok");//return "ok" stringresponse.getWriter().flush();} catch (IOException e) {    //handle exception...}} else {      setAlwaysUseDefaultTargetUrl(false);  ...}}
}

为登录失败定义一个处理程序–与成功相同,但是字符串为“ not-ok”。

我知道这里的某些代码不是最佳做法,所以我想听听您的想法。
如果您能看到改进流程或使其更通用的方法,请发给我。

鸣谢:通过gliffy完成了图表-在线图表工具

参考: Spring security 3 Ajax登录–通过 Gal Levinsky博客博客中的JCG合作伙伴 Gal Levinsky 访问受保护的资源 。


翻译自: https://www.javacodegeeks.com/2012/08/spring-security-3-ajax-login-accessing.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372060.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

测试环境下将centos6.8升级到centos7的操作记录(转)

在测试环境下安装openstack&#xff0c;由于在centos6下安装openstack&#xff0c;针对源的问题有很多&#xff0c;安装起来很不顺利&#xff01; 但是在centos7下安装却很顺利&#xff0c;所以考虑将服务器由centos6升级到centos7 这个我是在测试机中运行的&#xff0c;建议不…

linux运维选择题,初学Linux练习题

1、将/etc/issue文件中的内容转换为大写后保存至/tmp/issue.out文件中tr ‘a-z’ ‘A-Z’ < /etc/issue > /tmp/issue.out2、将当前系统登录用户的信息转换为大写后保存至/tmp/who.out文件中3、一个linux用户给root发邮件&#xff0c;要求邮件标题为”help”&#xff0c…

[转]Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务

本文转自&#xff1a;http://www.cnblogs.com/fzrain/p/3923727.html 前言 很久没更新了&#xff0c;之前有很多事情&#xff0c;所以拖了很久&#xff0c;非常抱歉。好了&#xff0c;废话不多说&#xff0c;下面开始正题。本篇仍然使用上一季的的项目背景&#xff08;系列地址…

使用Spring 3 MVC处理表单

本文是有关Spring 3的一系列文章的一部分。该系列的上一篇文章可以在此处获得 。 在本文中&#xff0c;我们向Spring MVC迈出了又一步。 [此外&#xff1a; 术语MVC的创建者提供的pdf 。]从上一篇文章构建&#xff0c;让我们添加将“联系人”添加到应用程序所需的代码。 首先&a…

插入排序法之——直接插入排序、折半插入排序、希尔排序

// test20.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<iostream> #include<vector> #include<string> #include<queue> #include<stack> #include<cstring> #include<string.h> #include<de…

linux idea 快捷键,Linux 下 IDEA 的 Ctrl+Alt+S

前言这是个困扰我一年多的问题&#xff0c;今天终于解决了……起因一年前将主系统换成 Arch Linux 后&#xff0c;其他一切正常就是 IDEA 的打开设置的快捷键 ctrlalts 失效&#xff0c;让我很是头疼。虽然不是很重要&#xff0c;但是对于我这种强迫症来说别提多难受了……我曾…

修改input的placeholder颜色

1、CSS选择器 因为每个浏览器的CSS选择器有所差异&#xff0c;所以需要针对每个浏览器做单独的设定。 ::-webkit-input-placeholder { /* WebKit browsers */ color: #999; } :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ color: #999; } ::-moz-placeholder { /* Mozil…

解决Spring自动装配中的循环依赖

我认为这篇文章是在企业应用程序开发中使用Spring的最佳实践。 使用Spring编写企业Web应用程序时&#xff0c;服务层中的服务量可能会增加。 服务层中的每个服务可能会消耗其他服务&#xff0c;这些服务将通过Autowire注入。 问题&#xff1a;当服务数量开始增加时&#xff0…

01.MD5加密

namespace _01.MD5加密{ class Program { static void Main(string[] args) { //MD5加密就是给想要的密码或者其它字符加密 //如果字符串被加密成MD5值之后,是不可逆的. //字符串123 的MD5 64位加密形式是 202cb962ac59075b964b07152d234b70 Console.WriteLine("请输入需要…

C语言数字3转变字符 3 程序,大学c语言知识点总结

大学c语言知识点总结C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。一起来看看大学c语言知识点总结吧!大学c语言知识点总结1、编译预处理不是C语言的一部分&#xff0c;不再运行时间。C语言编…

接触Jenkins(Hudson)API,第1部分

哪一个-哈德森还是詹金斯&#xff1f; 都。 几个月前&#xff0c;我开始使用Hudson v1.395来从事这个小项目&#xff0c;在出现巨大分歧之后又回到了这个项目。 我以此为契机&#xff0c;看我将来选择永久搬到詹金斯时是否会遇到任何重大问题。 有很多麻烦-最值得注意的是&…

使用javascript模拟常见数据结构(四)

七、树 树是一种非线性的分层的数据结构&#xff0c;在现实生活中比较常见的例子比如家谱和公司的组织架构图&#xff0c;如下所示&#xff1a; 一个树结构存在着一系列的父子结构&#xff0c;并且有着一个根节点&#xff0c;这种结构本质上表明了一对多的关系。 那&#xff0c…

C语言中实际参数太多,c – 宏的实际参数太多了?

码&#xff1a;#include using namespace std;#define ADD(x,y) ((x)(y))int main( int argc, char** argv ){cout << ADD(1,2,) << endl;return 0;}编译器输出&#xff1a;1>Compiling…1>main.cpp1>c:\warn_test\main.cpp(9) : warning C4002: too many…

Web开发框架–第2部分:Play Framework 2.0

作为 评估系列 的第一个候选人&#xff0c; 我们回顾了 Play Framework v2.0 。 可以从Play 文档站点获得本文所使用的教程和参考文档。 本文的第一部分将介绍我们建议对每个框架执行的一组任务&#xff0c;然后继续评估每个标准项。 在开发工作站中安装框架 非常简单&#…

最全Pycharm教程(10)——Pycharm调试器总篇

最全Pycharm教程&#xff08;1&#xff09;——定制外观 最全Pycharm教程&#xff08;2&#xff09;——代码风格 最全Pycharm教程&#xff08;3&#xff09;——代码的调试、执行 最全Pycharm教程&#xff08;4&#xff09;——有关Python解释器的相关配置 最全Pycharm教程&am…

Looper.prepare()和Looper.loop()

什么时候需要 Looper Looper用于封装了android线程中的消息循环&#xff0c;默认情况下一个线程是不存在消息循环&#xff08;message loop&#xff09;的&#xff0c;需要调用Looper.prepare()来给线程创建一个消息循环&#xff0c;调用Looper.loop()来使消息循环起作用&#…

超速问题的c语言编程,超速行驶问题--精选.doc

超速行驶问题摘要本文主要研究的是探讨驱车从始发地至目的地的最短时间路径问题和最少花费问题&#xff0c;以及在超速情况下的最短时间和最少花费问题。首先&#xff0c;从整个题目的两个问题入手&#xff0c;发现两个问题都是优化问题&#xff0c;具有一定的联系。然后针对第…

重新查看Play Framework发布的值

与Play Framework 2.0一起使用发布的值而不定义表单映射&#xff0c;可能不像Play 1.x那样明显&#xff0c;这就是为什么我要编写此快速备忘单。 对于此快速示例&#xff0c;让我们定义以下视图&#xff1a; app / views / index.scala.html (message: String)message: messa…

matlab 微积分

符号变量&#xff0c;symbolic variable 1. 高阶导数 高阶导数的计算&#xff0c;当然可以用手工的方式&#xff0c;但显然这种机械重复的推导&#xff0c;更适用于计算机的计算方式&#xff1a; f(x)sinxx24x3⇒d4fdx4>> syms x; >> f sin(x) / (x^24*x3); >&…

如何查看Ubuntu版本,以及Linux内核版本??

查看Ubuntu版本&#xff1a; 方法一&#xff1a; cat /etc/issue 方法二&#xff1a; sudo lsb_release -a 查看内核版本&#xff1a; uname -r 转载于:https://www.cnblogs.com/tanrong/p/6937749.html