2011-11-03 38 views
6

Ngay bây giờ, bộ cân bằng tải xử lý https và sau đó chuyển qua https đó tới máy chủ web của tôi. Vì vậy, giao dịch với https tăng gấp đôi cho mỗi yêu cầu. Những gì tôi muốn làm là hoàn toàn offload https vì vậy máy chủ web của tôi không phải đối phó với nó.Tắt https để tải cân bằng với Spring Security

Làm cách nào để định cấu hình các trang Spring Security và JSP cho rằng máy chủ web nghĩ rằng tất cả các yêu cầu là http? Rõ ràng tôi sẽ phải sửa đổi các thành phần <intercept-url> trong cấu hình của mình để có thuộc tính requires-channel luôn là http hoặc any. Trong các trang JSP của tôi, tôi sẽ phải thêm các liên kết <c:url value=''/> với ${secureUrl}${nonSecureUrl} tùy thuộc vào việc trang kết quả cần phải là https hay http. Chuyển hướng từ bộ điều khiển cần phải được sửa đổi như thế này là tốt ... Bất cứ điều gì khác?

Có vẻ như khá đau khi sửa đổi tất cả các liên kết trong các trang JSP để bao gồm lược đồ và máy chủ. Có cách nào tốt hơn để làm điều đó không?

Trả lời

6

Nếu bạn chấm dứt SSL ở bộ cân bằng tải thì trình cân bằng tải của bạn sẽ gửi tiêu đề cho biết giao thức ban đầu được yêu cầu. Ví dụ, F5 thêm X-Forwarded-Proto.

Từ đây bạn có thể tạo tùy chỉnh ChannelProcessor s xem tiêu đề này thay vì xem request.isSecure(). Sau đó, bạn có thể tiếp tục sử dụng <intercept-url requires-channel="https"> và tương đối <c:url>.

Các bước:

  1. Subclass SecureChannelProcessorInsecureChannelProcessor trọng decide(). Trong decide() kiểm tra tiêu đề được gửi bởi bộ cân bằng tải của bạn.

    @Override 
    public void decide(FilterInvocation invocation, Collection<ConfigAttribute> config) throws IOException, ServletException { 
    
        for (ConfigAttribute attribute : config) { 
         if (supports(attribute)) { 
          if (invocation.getHttpRequest(). 
            getHeader("X-Forwarded-Proto").equals("http")) { 
           entryPoint.commence(invocation.getRequest(), 
            invocation.getResponse()); 
          } 
         } 
        } 
    } 
    
  2. Sau đó thiết lập những ChannelProcessors trên đậu ChannelDecisionManagerImpl sử dụng một BeanPostProcessor. Xem điều này Spring Security FAQ về lý do/cách sử dụng BeanPostProcessor cho việc này.

+0

thử các bước trên, phương pháp quyết định không được gọi, có bất kỳ điều gì khác chúng ta cần phải cấu hình không? –

1

Có vẻ như Grails hỗ trợ điều này như một phần của plugin bảo mật. Kiểm tra phần dưới cùng của http://grails-plugins.github.com/grails-spring-security-core/docs/manual/guide/17%20Channel%20Security.html nơi họ nói về việc kiểm tra các tiêu đề yêu cầu mà LB sẽ đặt.

grails.plugins.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true 
grails.plugins.springsecurity.secureChannel.secureHeaderName = '...' 
grails.plugins.springsecurity.secureChannel.secureHeaderValue = '...' 
grails.plugins.springsecurity.secureChannel.insecureHeaderName = '...' 
grails.plugins.springsecurity.secureChannel.insecureHeaderValue = '...' 
2

Để hoàn thành câu trả lời sourcedelica tuyệt vời, đây là mã đầy đủ:

Đối Bước 1:

@Component 
public class SecureChannelProcessorHack extends SecureChannelProcessor { 

@Override 
public void decide(FilterInvocation invocation, Collection<ConfigAttribute> config) throws IOException, ServletException { 
    for (ConfigAttribute attribute : config) { 
     if (supports(attribute)) { 
      if ("http".equals(invocation.getHttpRequest().getHeader("X-Forwarded-Proto"))) { 
       getEntryPoint().commence(invocation.getRequest(), 
         invocation.getResponse()); 
      } 
     } 
    } 
} 
} 



@Component 
public class InsecureChannelProcessorHack extends InsecureChannelProcessor { 

@Override 
public void decide(FilterInvocation invocation, Collection<ConfigAttribute> config) throws IOException, ServletException { 
    for (ConfigAttribute attribute : config) { 
     if (supports(attribute)) { 
      if ("https".equals(invocation.getHttpRequest().getHeader("X-Forwarded-Proto"))) { 
       getEntryPoint().commence(invocation.getRequest(), 
         invocation.getResponse()); 
      } 
     } 
    } 
} 
} 

Và bước 2:

@Configuration 
public class LoadBalancerHack implements BeanPostProcessor { 

@Inject 
SecureChannelProcessorHack secureChannelProcessorHack; 

@Inject 
InsecureChannelProcessorHack insecureChannelProcessorHack; 

@Value("${behind.loadbalancer?false}") 
boolean behindLoadBalancer; 

@Override 
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 
    return bean; 
} 

@Override 
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 
    if (behindLoadBalancer && bean instanceof ChannelDecisionManagerImpl) { 
     System.out.println("********* Post-processing " + beanName); 
     ((ChannelDecisionManagerImpl) bean).setChannelProcessors(newArrayList(
       insecureChannelProcessorHack, 
       secureChannelProcessorHack 
     )); 
    } 
    return bean; 
} 

} 
Các vấn đề liên quan