简体   繁体   English

带有AJAX的Spring Security发布请求(注销)

[英]Spring security post request with AJAX (Logout)

As I am moving from Spring 3.1.1.RELEASE to 4.0.2 RELEASE I have had to make some changes to spring security context. 当我从Spring 3.1.1.RELEASE迁移到4.0.2 RELEASE时,我不得不对Spring安全上下文进行一些更改。

Almost everything is ok except POST Request for logout. 除了POST请求注销外,几乎一切都OK。

I could make entire line to be form method="POST" action="logout" but then I have to deal with Submit which is totally different styling then what we need. 我可以将整个行设置为method =“ POST” action =“ logout”,但是然后我必须处理Submit,这与我们需要的样式完全不同。 I have tried sending logout request with csrf data over ajax with no success. 我尝试通过ajax发送带有csrf数据的注销请求,但未成功。 Any help is greatly appreciated. 任何帮助是极大的赞赏。 PS Disabling csrf is not an option. PS禁用csrf不是一种选择。

 <!-- JSP -->
 <meta name="_csrf" content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>

<!--Anchor -->
<a id="loggg" href="logout">Logout1</a>

<!-- jquery -->
$("#loggg").click(function(e){
    e.preventDefault();
     var token = $("meta[name='_csrf']").attr("content");
      var header = $("meta[name='_csrf_header']").attr("content");
    $.ajax({
        url : "logout",
        method : "POST",
        data :token ,
        success : function(data) { 
            console.log("clicked");
        }, 
        error : function(data) {
            console.log(data);
        }
    });

})

FireBug developer console returns : FireBug开发人员控制台返回:

403 Forbidden 2ms
"NetworkError: 403 Forbidden - http://localhost:8081/nekretnine/logout"
Object { readyState=4,  responseText="<!DOCTYPE html><html> 
<he...EASE</h3></body></html>",  status=403,  more...}

If your login is an AJAX request from the same page, that would have changed the token in the server. 如果您的登录名是来自同一页面的AJAX请求,那将更改服务器中的令牌。 Spring Security changes the token in events like login and logout . Spring Security在诸如loginlogout之类的事件中更改令牌

So, your token in the page would no more be valid. 因此,页面中的令牌将不再有效。

If this turns out to be the case, one way would be to fetch the new token using a GET request after having a filter attaching the token as a cookie, as explained here . 如果这原来是这样的,一个办法是有过滤器安装令牌作为cookie后取出使用GET请求新的令牌,如解释在这里

This also might be helpful. 也可能会有所帮助。

I have managed to partially solve this issue. 我设法部分解决了这个问题。 This answer is for those who might stumble on to the same problem as i did when i moved from Spring Security 3.1.1 to Spring security 4.0.2 该答案适用于那些可能会遇到与我从Spring Security 3.1.1迁移到Spring Security 4.0.2时遇到的问题相同的问题的人

JSP JSP

 <meta name="_csrf" content="${_csrf.token}"/>
 <!-- default header name is X-CSRF-TOKEN -->
 <meta name="_csrf_header" content="${_csrf.headerName}"/>

Anchor

<a id="loggg" href="logout">Logout1</a>

Jquery jQuery的

$("#loggg").click(function(e){
    e.preventDefault();
     var token = $("meta[name='_csrf']").attr("content");
      var header = $("meta[name='_csrf_header']").attr("content");
    $.ajax({
        url : 'logout',
        type : 'POST',
        data: token,
        beforeSend:function(xhr){
             xhr.setRequestHeader(header, token);
        },
        success : function(data) { 
            window.location ="/home";    here is the only problem, for some reason after logging out page doesnt refresh and i can still see myself logged in. Then i usually just press f5 and i am logged out.
        }, 
        error : function(data) {
            console.log(data);
        }
    });

})

Few problems i noticed when i changed from Spring security 3 to Spring Security 4. Here are some : 从Spring Security 3更改为Spring Security 4时,我注意到的几个问题如下:

Attributes are no longer j.username i j.password instead use- username password 属性不再是j.username i j.password,而是使用-用户名密码

  1. Action is no longer j_spring_security_check ,instead use - login 操作不再是j_spring_security_check,而是使用-登录
  2. Logout action is no longer j_spring_security_logout use logout 注销操作不再j_spring_security_logout使用注销
  3. Request must be post, even for logout. 请求必须发布,即使注销也是如此。
  4. U need to add CSRF token 你需要添加CSRF令牌

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

to forms, or if u use spring forms, csrf.token will be added automatically. 形式,或者如果您使用弹簧形式,csrf.token将自动添加。 Also u can use 你也可以用

u need to add these filters ( u must add them before Spring security filter) 您需要添加这些过滤器(您必须在Spring安全过滤器之前添加它们)

<filter>
        <display-name>springMultipartFilter</display-name>
             <filter-name>springMultipartFilter</filter-name>
        <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
    </filter>
    <filter-mapping>
             <filter-name>springMultipartFilter</filter-name>
             <url-pattern>/*</url-pattern>
    </filter-mapping>
  1. You were probably using multipartResolver resolver bean, which you will need to change to <beans:bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <beans:property name="maxUploadSize" value="-1" /> 您可能正在使用multipartResolver解析器bean,您需要将其更改为<beans:bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <beans:property name="maxUploadSize" value="-1" />

  2. Also if you have done all this and you still cant upload files using commons-fileUpload you (as myself) probably placed filterMultyPartResolver in servlet-context , which was working just fine in previous version, now with no compile errors you will just end up in a dead-end street not knowing what to do. 另外,如果您已完成所有这些操作,但仍然无法使用commons-fileUpload上传文件(您自己),则可能将filterMultyPartResolver放置在servlet-context中,这在以前的版本中工作得很好,现在没有编译错误,您将最终陷入一条不知所措的死胡同。 Solution is very simple, just move bean to root-context.xml and voala! 解决方案非常简单,只需将bean移至root-context.xml并执行voala! all is working perfectly. 一切运行正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM