2011-11-03 2 views
6

현재로드 밸런서는 https를 처리 한 다음 해당 https를 웹 서버에 전달합니다. 따라서 각 요청에 대해 https double을 처리합니다. 제가하고 싶은 것은 https를 완전히 오프로드하여 웹 서버가 그것을 처리 할 필요가 없기 때문입니다.스프링 보안이 적용된로드 밸런서에 https 오프로드

웹 서버가 모든 요청이 http라고 생각하면 스프링 보안 및 JSP 페이지를 어떻게 구성합니까? 분명히 requires-channel 속성이 항상 http 또는 any이되도록 구성의 <intercept-url> 요소를 수정해야합니다. 내 JSP 페이지에서 결과 페이지가 https 또는 http 여야하는지 여부에 따라 ${secureUrl}${nonSecureUrl}과 함께 <c:url value=''/> 링크를 앞에 추가해야합니다. 컨트롤러에서 리다이렉트 (redirects)는 이와 같이 수정 될 필요가있다.

JSP 페이지의 모든 링크를 수정하여 스키마와 호스트를 포함하는 것은 상당히 고통 스럽습니다. 그렇게 할 수있는 더 좋은 방법이 있습니까?

답변

6

로드 밸런서에서 SSL을 종료하면로드 밸런서는 원래 요청 된 프로토콜을 나타내는 헤더를 보내야합니다. 예를 들어, F5는 X-Forwarded-Proto를 추가합니다.

여기서 request.isSecure() 대신이 머리글을 보는 맞춤 ChannelProcessor을 만들 수 있습니다. 그런 다음 <intercept-url requires-channel="https"> 및 관련 <c:url>을 계속 사용할 수 있습니다.

단계 : SecureChannelProcessorInsecureChannelProcessordecide()를 오버라이드 (override)

  1. 서브 클래스입니다. decide()에서로드 밸런서가 보낸 헤더를 확인하십시오.

    @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. 는 그런 다음 BeanPostProcessor를 사용하여 ChannelDecisionManagerImpl 콩에서 이러한 ChannelProcessors을 설정합니다. 이 경우 BeanPostProcessor을 사용하는 이유/방법에 대해서는 Spring Security FAQ을 참조하십시오.

+0

위의 단계를 시도, 결정 방법이 불려지지 않는다면, 우리가 설정해야 할 것이 있습니까? –

1

Grails가 이것을 보안 플러그인의 일부로 지원하는 것처럼 보입니다. http://grails-plugins.github.com/grails-spring-security-core/docs/manual/guide/17%20Channel%20Security.html의 하단 섹션에서 LB가 설정할 요청 헤더를 확인하는 방법에 대해 설명합니다.

@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()); 
      } 
     } 
    } 
} 
} 

그리고 2 단계 : 1 단계의 경우

:

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

위대한 sourcedelica 응답을 완료하려면, 여기에 전체 코드

@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; 
} 

} 
관련 문제