2014-09-01 25 views
5

Gần đây chúng tôi đã giới thiệu bảo vệ CSRF cho dự án của chúng tôi sử dụng bảo mật mùa xuân 3.2.Bộ điều khiển thử nghiệm đơn vị có bảo vệ CSRF được bật trong bảo mật mùa xuân

Sau khi bật CSRF, một số kiểm tra đơn vị bị lỗi do mã thông báo csrf không có sẵn theo yêu cầu. Tôi đặt một số giá trị giả vào tham số '_csrf' và nó không hoạt động.

Có cách nào để tôi có thể nhận mã thông báo csrf trước khi gửi yêu cầu (khi kiểm tra đơn vị) không?

Trả lời

0

Tôi đã tìm thấy một công việc xung quanh để khắc phục sự cố này bằng cách tạo triển khai CsrfTokenRepository tùy chỉnh. Điều này sẽ luôn tạo ra một mã thông báo không đổi (như "test_csrf_token"). Vì vậy, chúng tôi có thể gửi mã thông báo đó dưới dạng tham số yêu cầu (vì nó sẽ không thay đổi) với các thông số biểu mẫu khác. Dưới đây là các bước tôi đã theo dõi để giải quyết vấn đề của tôi.

  1. tạo lớp triển khai giao diện CsrfTokenRepository. Triển khai mã thông báo tạo với một số giá trị mã thông báo không đổi.

    public CsrfToken generateToken(HttpServletRequest request) { 
        return new DefaultCsrfToken(headerName, parameterName, "test_csrf_token"); 
    } 
    
    @Override 
    public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) { 
        if (token == null) { 
         HttpSession session = request.getSession(false); 
         if (session != null) { 
          session.removeAttribute(sessionAttributeName); 
         } 
        } else { 
         HttpSession session = request.getSession(); 
         session.setAttribute(sessionAttributeName, token); 
        } 
    } 
    
    @Override 
    public CsrfToken loadToken(HttpServletRequest request) { 
        HttpSession session = request.getSession(false); 
        if (session == null) { 
         return null; 
        } 
        return (CsrfToken) session.getAttribute(sessionAttributeName); 
    } 
    
  2. Thêm tham chiếu vào thẻ csrf trong cấu hình bảo mật của bạn.

    <http> 
        <csrf token-repository-ref="customCsrfTokenRepository" /> 
        .... 
    </http> 
    
    <beans:bean id="customCsrfTokenRepository" class="com.portal.controller.security.TestCsrfTokenRepository"></beans:bean> 
    
  3. Sửa đổi trường hợp thử nghiệm của bạn bằng cách thêm thông số yêu cầu csrf.

    request.addParameter("_csrf", "test_csrf_token"); 
    
14

uiroshan câu trả lời của bạn là đánh bại mục đích của CSRF mã thông báo: với cấu hình của bạn bây giờ nó sẽ là một giá trị không đổi (trừ khi cấu hình của bạn chỉ được sử dụng trong bối cảnh thử nghiệm của bạn, nhưng bạn không nói rõ nó) .

Quyền (và dễ dàng hơn) cách để giải quyết vấn đề này là:

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; 

... 

@Test 
public void testLogin() throws Exception { 
    this.mockMvc.perform(post("/login") 
      .param("username", "...") 
      .param("password", "...") 
      .with(csrf())) 
     .andExpect(status().isFound()) 
     .andExpect(header().string("Location", "redirect-url-on-success-login")); 
} 

Phần quan trọng là: .with(csrf()) mà sẽ bổ sung dự kiến ​​_csrf tham số để truy vấn.

Các csrf() phương pháp tĩnh được cung cấp bởi spring-security-test:

<dependency> 
    <groupId>org.springframework.security</groupId> 
    <artifactId>spring-security-test</artifactId> 
    <version>4.2.4.RELEASE/5.0.2.RELEASE</version> 
    <scope>test</scope> 
</dependency> 

kiểm tra đơn vị của bạn sẽ yêu cầu nhập khẩu sau đây để truy cập vào nó:

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*; 
Các vấn đề liên quan