2012-09-13 1 views
3

에서 http 포트에 대한 HTTPS 포트 번호를 해당 가져 오기, 그리고 제거 할 것 중 하나는 포트 번호 매핑 :내 웹 애플리케이션의 구성을 최소화하기 위해 노력하고있어 톰캣

  • HTTP : 80 - >은 https :
  • HTTP 443 : 9080 -> HTTPS : 9443

구성이 이미 conf의/server.xml에 존재하기 때문에, 나는 내 응용 프로그램에서 이러한 설정을 복제하고 싶지 않아요. 여러 설정 파일을 변경해야한다는 것은 고통 스럽습니다. 또한 응용 프로그램은 http 및 https를 지원하는 한 배포 된 환경/컨테이너를 신경 쓰지 않아야합니다.

내가 내 web.xml 파일에 구성된 다음,하지만 내가 리디렉션에 추가 된 HTTPS URL을 구축 할 수 있어야

:

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>secure</web-resource-name> 
     <url-pattern>/https/*</url-pattern> 
    </web-resource-collection> 
    <user-data-constraint> 
     <transport-guarantee>CONFIDENTIAL</transport-guarantee> 
    </user-data-constraint> 
</security-constraint> 

위의 블록에 대한 HTTP 요청을 리디렉션하는 서블릿 컨테이너를 알려줍니다 그 https와 일치합니다. 당연히 Tomcat은 요청한 커넥터가 무엇인지 알며 해당 커넥터의 server.xml에서 "redirectPort"속성을 조회하고이를 사용하여 https URL을 만듭니다.

:

이 이전/관련 질문에 따르면, 요청에 해당하는 HTTPS 포트를 얻기의 표준 또는 바람둥이 특정 방법이있을 것 같지 않습니다

TL : 내 질문은 웹 응용 프로그램에서 명시 적으로 구성하지 않아도 안전하지 않은 요청에 해당 https 포트 번호를 가져 오는 데 어떤 아이디어가 있습니까?

내가 가진 한 가지 아이디어는 현재 요청과 동일한 포트 번호를 사용하는 보안 제약 뒤에있는 경로로 webapp에서 http 호출을하고 응답에서 리디렉션 위치를 구문 분석하는 것입니다. 물론 응답을 캐싱해야합니다. 더 간단한 방법이 있습니까?

편집 : 아이디어 코드를 사용하여 answer을 추가했습니다.

답변

-1

왜 보안 포트 번호를 알아야하는지 알 수 없습니다. 액세스되는 리소스가 SSL을 요구하는 것으로 표시되면 Tomcat은 https : 및 적절한 보안 포트로 리디렉션을 보냅니다. 이것이 server.xml의 구성입니다.

+0

안녕 EJP는 안전하지 않은 홈페이지에 가입 양식 (예 : http://facebook.com, http://twitter.com)이있는 경우를 고려하십시오. https 포트 (443이 아닌 경우)를 몰라도 양식 활동에 대한 https URL을 어떻게 생성합니까? Tomcat 리디렉션은 보안 URL로 리디렉션되기 전에 사용자가 데이터를 안전하지 않게 게시 한 것이므로 충분하지 않습니다. – andy

1

내가 질문에서 제안한 아이디어를 구현하는 방법을 알고 싶어하는 경우, 테스트를 위해 정리 한 몇 가지 샘플 코드가 있습니다. 나는이 솔루션으로 갈 것이라고 생각하지 않습니다.

이것은 질문 본문의 보안 제한 조건 블록과 작동합니다.

private static final String HTTPS_CONSTRAINED_PATH = "/https"; 

private static ConcurrentHashMap<String, Integer> resolvedHttpsPortMap = new ConcurrentHashMap<String, Integer>(); 
private static final ReentrantLock portMapLock = new ReentrantLock(); 

public static int resolveHttpsPort(HttpServletRequest request) { 
    if (request.isSecure()) return request.getServerPort(); 
    String key = request.getServerName() + ":" + request.getServerPort(); 
    Integer port = resolvedHttpsPortMap.get(key); 
    if (port == null) { 
     portMapLock.lock(); 
     try { 
      port = resolvedHttpsPortMap.get(key); 
      if (port == null) { 
       URL url = new URL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath() + HTTPS_CONSTRAINED_PATH); 
       HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
       if (conn.getResponseCode() != 301 && conn.getResponseCode() != 302 
         && conn.getResponseCode() != 303 && conn.getResponseCode() != 307) { 
        throw new IllegalStateException("Got unexpected response code " + conn.getResponseCode() + " from URL: " + url); 
       } 
       String location = conn.getHeaderField("Location"); 
       if (location == null) { 
        throw new IllegalStateException("Did not get a Location header in the response from URL: " + url); 
       } 
       URL locationUrl = new URL(location); 
       port = locationUrl.getPort(); 
      } 
     } catch (Exception e) { 
      logger.warn("Could not determine corresponding HTTPS port for '" + key + "'", e); 
     } finally { 
      if (port == null) port = -1; 
      resolvedHttpsPortMap.put(key, port); 
      portMapLock.unlock(); 
     } 
    } 
    return port; 
} 
관련 문제