首页 文章

Spring后端的REST安全CSRF保护 - 将Synchronizer Token Pattern传输到客户端

提问于
浏览
2

我读了很多关于Spring Securitys CSRF保护的内容,但我还是有点挣扎 . 现在文档像往常一样很棒,但它完全基于你在服务器上呈现html代码并且能够为每个表单添加隐藏字段的想法 . 现在,因为我使用AngularJS和JavaScript来调用后端,所以这不是一个真正的选择 .

那么在这种情况下实际获取令牌到客户端的最佳方法是什么(Rest Backend / AngularJS前端)? AngularJS似乎在$ resource中内置了对CSRF的支持,并期望一个名为“XSRF-TOKEN”的Cookie来检索令牌并在进一步的请求中将其作为http头“X-XSRF-TOKEN”发送 . 因此,每个请求都将包含http标头以及cookie . 现在在服务器端,我可以读取 Headers 并将其与存储在会话中的令牌进行比较 .

我有这个问题,它似乎有点复杂 . 由于登录本身必须受到保护,因此需要创建一个临时会话,仅用于CSRF令牌 . 这真的有必要吗?

也许这只是一个愚蠢的问题,但为什么我不能在客户端创建一个随机令牌并在客户端将其设置为HTTP头和cookie . 这类似于“OWASP double submit cookie”,但在客户端生成令牌 . 这样服务器就不需要在登录前进行会话,因为他可以只比较2个提交的令牌 . 现在虽然攻击者可以发送HTTP标头,但他会根据同源策略无法读取或设置cookie,并且只要该数字实际上是不可知的就无法获得匹配 .

现在本能地在客户端生成安全令牌对我来说似乎很危险,我想我可以避免它..但是为什么?我觉得我错过了一些东西,肯定有一个很好的理由让SpringSecurity将令牌存储在会话中,对吧?

请赐教:)

1 回答

  • 1

    我最终使用了spring-security-csrf-token-interceptor-extended,它从http-header "X-CSRF-TOKEN"(名称是可配置的)读取CSRF-Token,并在进一步请求时将其作为http-header发送 .

    现在我唯一要做的就是让Spring-Security将Token作为HTTP Header发送(因为我不在服务器端渲染HTML代码,因此无法将其添加为隐藏字段) .

    <security:http ....
         <security:custom-filter ref="csrfTokenResponseHeaderBindingFilter" after="CSRF_FILTER"/>
     ....
     </security:http>
    

    过滤器基本上在正常CSRF_FILTER之后运行并读取“_csrf”请求属性(由CSRF_FILTER放置)并将其设置为 Headers “X-CSRF-TOKEN”

    public class CsrfTokenResponseHeaderBindingFilter extends OncePerRequestFilter {
        protected static final String REQUEST_ATTRIBUTE_NAME = "_csrf";
        protected static final String RESPONSE_TOKEN_NAME = "X-CSRF-TOKEN";
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, javax.servlet.FilterChain filterChain) throws ServletException, IOException {
            CsrfToken token = (CsrfToken) request.getAttribute(REQUEST_ATTRIBUTE_NAME);
    
            if (token != null) {
                response.setHeader(RESPONSE_TOKEN_NAME, token.getToken());
            }
    
            filterChain.doFilter(request, response);
        }
    }
    

相关问题