升級完后,發現登錄不進去,把post改成get好了,但是系統的提交表單功能都不能用了,也是解決了很長時間,最后找到了根本原因。
spring sercurity 4.0 csrf保護是默認開啟的,csrf過濾器會檢查post過來的數據有沒有token,沒有則失敗。
解決方法一:加入<csrf disabled="true" />配置
解決方法二:不過濾指定的url
自己弄一個Matcher
1 package com.cnblogs.yjmyzz.utils;
2
3 import java.util.List;
4 import java.util.regex.Pattern;
5
6 import javax.servlet.http.HttpServletRequest;
7
8 import org.springframework.security.web.util.matcher.RequestMatcher;
9
10 public class CsrfSecurityRequestMatcher implements RequestMatcher {
11 private Pattern allowedMethods = Pattern 12 .compile("^(GET|HEAD|TRACE|OPTIONS)$");
13
14 public boolean matches(HttpServletRequest request) {
15
16 if (execludeUrls != null && execludeUrls.size() > 0) {
17 String servletPath = request.getServletPath();
18 for (String url : execludeUrls) {
19 if (servletPath.contains(url)) {
20 return false;
21 }
22 }
23 }
24 return !allowedMethods.matcher(request.getMethod()).matches();
25 }
26
27 /**
28 * 需要排除的url列表
29 */
30 private List<String> execludeUrls;
31
32 public List<String> getExecludeUrls() {
33 return execludeUrls;
34 }
35
36 public void setExecludeUrls(List<String> execludeUrls) {
37 this.execludeUrls = execludeUrls;
38 }
39 }
這里添加了一個屬性execludeUrls,允許人為排除哪些url。
然后在配置文件里,這樣修改:
1 <http entry-point-ref="loginEntryPoint" use-expressions="true">
2 ...
3 <intercept-url pattern="/rest/**" access="permitAll" />
4 ...
5 <csrf request-matcher-ref="csrfSecurityRequestMatcher"/>
6 </http>
7
8 <beans:bean id="csrfSecurityRequestMatcher" class="com.cnblogs.yjmyzz.utils.CsrfSecurityRequestMatcher">
9 <beans:property name="execludeUrls">
10 <beans:list>
11 <beans:value>/rest/</beans:value>
12 </beans:list>
13 </beans:property>
14 </beans:bean>
這里約定所有/rest/開頭的都是Rest服務地址,上面的配置就把/rest/排除在csrf驗證的范圍之外了.
解決方法三:加入csrf的token
參考http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf-logout