画布 1
http csrf处理流程
  csrfFilter
    1. 获取请求真实的actualToken 通过request.getHeader(csrfToken.getHeader
Name)
2. 获取的actualToken与前面获取的csrftoken.gettoken()中的token比较
      比较通过http header中的csrf_token与 获取到的Cap4jCsrfToken token是否一致，一致则正确，否则校验不通过
Cap4jCsrfToken.getToken().equals(request.getHeader(Cap4jCsrfToken.getHeaderName()))
      Cap4jCsrfToken.gettoken 返回key的tokenid
        因为key是保存的Referer的，所以实质是用本次请求Header中的与Referer tokenid进行比较
    1. defaultRequiresCsrfMatcher.alowedMatchods.matcher(requests.getMethod()).matches();
      Cap4jRequiresCsrfMatches类 过滤不进行校验的请求，例如GET、HEAD、TRACE、OPTION不进行校验
    1. 通过tokenRepository.loadToken(request) 获取csrfToken(不同的Repository实现不同)
      通过xml配置 <sec: csrf request-matcher-ref=... /> 传递 自定义Cap4jRequiresCsrfMatches、Cap4jcsrftokenRepository
        cap4jcsrftokenRepository 实现方式：
1.通过session获取 cap4jcsrftoken
cap4jcsrftokenRepository的loadToke()获取
cap4jcsrftoken(session.getAttribute(sessionAttributeName))，取不到就新建一个。
2. 把csrfToken保存到request
request.setAttribute() // CsrfToken.class.getName 、CsrfToken.getparameterName
        cap4jcsrftokenRepository.loadToke 返回的是cap4jcsrftoken
          其中csrfMap是历次get请求保存的url map，
          key：http Referer url 的 RequestURL
          subkey: 本次请求的RequestURL
      HttpSessionCsrfTokenRepository Httpsession的实现
      CookieCsrfTokenRepository cookie 实现方法
        这里有个问题csrftoken存放到cookie安全吗? 因为如果诱导点击链接发送请求是在请求中可以带上cookie的，但是把cookie带到后端也是没有用的，因为是需要在前端代码中通过csrfToken.getParameterName() 获取tokenid传入后端的，诱导的网站不知道getParameterName也无法获取csrf tokenid的
          例如js代码 $.cookie('XSRF-TOKEN');
        设置 withHttpOnlyFalse 允许通过js获取cookie
    引入 org.springFramework.security.web.csrf 包
  cap4jcsrfFilter
    1. 通过request.getAttribute(CsrfToken.class.getName())获取Cap4jCsrfToken
2. 判断不是Ajax post请求，则保存到request.(request.setAttribute(_csrf_key, subkey))。
  jsp页面自定义标签 <sec: csrfMetaTags />
      1. 通过 csrfMetaTagsTag 类添加
如图所示html标签代码，在页面端添加csrf token
2. 前端代码组件在发起请求时会获取csrf token添加到 header 参数里面，这样下次请求csrfFilter 会校验通过
    1. 通过this.pageContext.getRequest().getAttribute(CsrfToken.class)获取 cap4jCsrfToken
2. 添加(key:{DEFAULT_KEY=tokenid}) 到 csrfMap
3. csrfMap 是保存在session 中的
    com.cib.cap4j.cfn.tags 主要包括下三个类 CsrfMetaTagsTag、AbstracDefaultCsrfTag 、AbstractCap4jCsrfTag
  csrfToken
1. getHeaderName() //获取请求csrftoken header中的的名字
2. getParameterName() // 前端隐藏的token的组件名字
3. getToken()
    前端发起POST(一般其它请求默认是不校验)请求之前，需要获取页面渲染后生成的csrftoken，参考前端代码
<body>
<form action="/hello" method="post">
<input type="hidden" th:value="${_csrf.token}" th:name="${_csrf.parameterName}">
<input type="submit" value="hello">
</form>
</body>
    自定义 Cap4jCsrfToken
Cap4jCsrfToken implements csrfToken
1. csrfMap
2. key：http Referer url 的 RequestURL
3. subkey: 这次请求的url 的RequestURL /custCombinationQuery/schemQuery.do
4. headerName:http head请求csrf名称，例如"X-CSRF-TOKEN"
5. parameterName 存放Csrftoken的key的名字， _csrf
6. token: tokenid
  csrfTokenRepository
1. generateToken
2. saveToken
3. loadToken
    Cap4jCsrfTokenRepository implements csrfTokenRepository
1. sessionAttributeName 是 session 存放Cap4jCsrfToken的key，这里为com.cib.cap4j.core.security.csrf.Cap4jcsrfTokenRepository.CSRF_TOKEN
1. SaveToken()
2. generateToken()
3. GetCsrkKey()
4.
    HttpSessionCsrfTokenRepository httpsession实现方法
    CookieCsrfTokenRepository cookie 实现方法