1장. HTTP 호환 바인딩에 대한 보안
초록
이 장에서는 Apache CXF HTTP 전송에서 지원하는 보안 기능에 대해 설명합니다. 이러한 보안 기능은 HTTP 전송 위에 계층화할 수 있는 모든 Apache CXF 바인딩에서 사용할 수 있습니다.
1.1. 개요
이 섹션에서는 일반적으로 HTTPS라는 조합인 SSL/TLS 보안을 사용하도록 HTTP 전송을 구성하는 방법을 설명합니다. Apache CXF에서 HTTPS 보안은 XML 구성 파일에 설정을 지정하여 구성됩니다.
SSL/TLS 보안을 활성화하는 경우 Poodle 취약점(CVE-2014-3566) 으로부터 보호하기 위해 SSLv3 프로토콜을 명시적으로 비활성화해야 합니다. 자세한 내용은 JBoss Fuse 6.x 및 JBoss A-MQ 6.x에서 SSLv3 비활성화 를 참조하십시오.
다음 주제는 이 장에서 설명합니다.
1.2. X.509 인증서 생성
SSL/TLS 보안을 사용하기 위한 기본 전제 조건은 서버 애플리케이션을 식별하는 데 X.509 인증서 컬렉션을 사용할 수 있고 선택적으로 클라이언트 애플리케이션을 식별하는 것입니다. 다음 방법 중 하나로 X.509 인증서를 생성할 수 있습니다.
- 상용 타사를 사용하여 X.509 인증서를 생성하고 관리합니다.
-
무료
openssl
유틸리티( http://www.openssl.org에서 다운로드할 수 있음) 및 Java키 저장소
유틸리티를 사용하여 인증서를 생성합니다( 2.5.3절. “CA를 사용하여 Java 키 저장소에서 서명된 인증서 생성”참조).
HTTPS 프로토콜은 서버가 배포된 호스트 이름과 일치하도록 인증서의 ID가 필요한 URL 무결성 검사를 수행해야 합니다. 자세한 내용은 2.4절. “HTTPS 인증서에 대한 특수 요구 사항” 을 참조하십시오.
1.3. 인증서 형식
Java 런타임에서는 X.509 인증서 체인과 신뢰할 수 있는 CA 인증서를 Java 키 저장소 형태로 배포해야 합니다. 자세한 내용은 3장. HTTPS 구성 을 참조하십시오.
1.4. HTTPS 활성화
WSDL 끝점에서 HTTPS를 활성화하기 위한 전제 조건은 엔드포인트 주소를 HTTPS URL로 지정해야 한다는 것입니다. 끝점 주소가 설정된 두 개의 다른 위치가 있으며 모두 HTTPS URL을 사용하도록 수정해야 합니다.
WSDL 계약에 지정된 HTTPS - 예 1.1. “WSDL에서 HTTPS 지정” 에 표시된 대로 WSDL 계약에 있는 엔드포인트 주소를 https: 접두사가 있는 URL로 지정해야 합니다.
예 1.1. WSDL에서 HTTPS 지정
<wsdl:definitions name="HelloWorld" targetNamespace="http://apache.org/hello_world_soap_http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ... > ... <wsdl:service name="SOAPService"> <wsdl:port binding="tns:Greeter_SOAPBinding" name="SoapPort"> <soap:address location="https://localhost:9001/SoapContext/SoapPort"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
soap:address
요소의location
속성이 HTTPS URL을 사용하도록 구성된 위치. Cryostat 이외의 바인딩의 경우http:address
요소의location
속성에 나타나는 URL을 편집합니다.서버 코드에 지정된 HTTPS -
Endpoint.publish()
를 호출하여 서버 코드에 게시된 URL이 예 1.2. “서버 코드에서 HTTPS 지정” 에 표시된 대로 https: 접두사로 정의되었는지 확인해야 합니다.예 1.2. 서버 코드에서 HTTPS 지정
// Java package demo.hw_https.server; import javax.xml.ws.Endpoint; public class Server { protected Server() throws Exception { Object implementor = new GreeterImpl(); String address = "https://localhost:9001/SoapContext/SoapPort"; Endpoint.publish(address, implementor); } ... }
1.5. 인증서가 없는 HTTPS 클라이언트
예를 들어 예 1.3. “인증서가 없는 샘플 HTTPS 클라이언트” 에 표시된 대로 인증서가 없는 보안 HTTPS 클라이언트의 구성을 고려하십시오.
예 1.3. 인증서가 없는 샘플 HTTPS 클라이언트
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xsi:schemaLocation="..."> <http:conduit name="{http://apache.org/hello_world_soap_http}SoapPort.http-conduit"> <http:tlsClientParameters> <sec:trustManagers> <sec:keyStore type="JKS" password="password" file="certs/truststore.jks"/> </sec:trustManagers> <sec:cipherSuitesFilter> <sec:include>.*_WITH_3DES_.*</sec:include> <sec:include>.*_WITH_DES_.*</sec:include> <sec:exclude>.*_WITH_NULL_.*</sec:exclude> <sec:exclude>.*_DH_anon_.*</sec:exclude> </sec:cipherSuitesFilter> </http:tlsClientParameters> </http:conduit> </beans>
이전 클라이언트 구성은 다음과 같이 설명되어 있습니다.
TLS 보안 설정은 특정 WSDL 포트에 정의됩니다. 이 예에서 구성 중인 WSDL 포트에는 QName {http://apache.org/hello_world_soap_http}SoapPort
.
http:tlsClientParameters
요소에는 클라이언트의 모든 TLS 구성 세부 정보가 포함됩니다.
sec:trustManagers
요소는 신뢰할 수 있는 CA 인증서 목록을 지정하는 데 사용됩니다(클라이언트는 이 목록을 사용하여 서버 측에서 수신된 인증서를 신뢰 여부를 결정합니다).
sec:keyStore
요소의 file
속성은 하나 이상의 신뢰할 수 있는 CA 인증서를 포함하는 Java 키 저장소 파일 truststore.jks
를 지정합니다. password
속성은 키 저장소인 truststore.jks
에 액세스하는 데 필요한 암호를 지정합니다. 3.2.2절. “HTTPS를 위한 신뢰할 수 있는 CA 인증서 지정”을 참조하십시오.
file
속성 대신 resource
속성(클래스 경로에 키 저장소 파일이 제공됨) 또는 url
특성을 사용하여 키 저장소의 위치를 지정할 수 있습니다. 특히 리소스
속성은 OSGi 컨테이너에 배포된 애플리케이션과 함께 사용해야 합니다. 신뢰할 수 없는 출처에서 신뢰 저장소를 로드하지 않도록 주의해야 합니다.
sec:cipherSuitesFilter
요소는 클라이언트가 TLS 연결에 사용할 암호화 제품군의 선택을 좁히는 데 사용할 수 있습니다. 자세한 내용은 4장. HTTPS Cipher Suites 구성 을 참조하십시오.
1.6. 인증서가 있는 HTTPS 클라이언트
자체 인증서를 갖도록 구성된 보안 HTTPS 클라이언트를 고려하십시오. 예 1.4. “인증서가 있는 샘플 HTTPS 클라이언트” 이러한 샘플 클라이언트를 구성하는 방법을 보여줍니다.
예 1.4. 인증서가 있는 샘플 HTTPS 클라이언트
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xsi:schemaLocation="..."> <http:conduit name="{http://apache.org/hello_world_soap_http}SoapPort.http-conduit"> <http:tlsClientParameters> <sec:trustManagers> <sec:keyStore type="JKS" password="password" file="certs/truststore.jks"/> </sec:trustManagers> <sec:keyManagers keyPassword="password"> <sec:keyStore type="JKS" password="password" file="certs/wibble.jks"/> </sec:keyManagers> <sec:cipherSuitesFilter> <sec:include>.*_WITH_3DES_.*</sec:include> <sec:include>.*_WITH_DES_.*</sec:include> <sec:exclude>.*_WITH_NULL_.*</sec:exclude> <sec:exclude>.*_DH_anon_.*</sec:exclude> </sec:cipherSuitesFilter> </http:tlsClientParameters> </http:conduit> <bean id="cxf" class="org.apache.cxf.bus.CXFBusImpl"/> </beans>
이전 클라이언트 구성은 다음과 같이 설명되어 있습니다.
sec:keyManagers
요소는 X.509 인증서와 개인 키를 클라이언트에 연결하는 데 사용됩니다. keyPasswod
속성에 의해 지정된 암호는 인증서의 개인 키를 해독하는 데 사용됩니다.
sec:keyStore
요소는 X.509 인증서와 Java 키 저장소에 저장된 개인 키를 지정하는 데 사용됩니다. 이 샘플은 키 저장소가 JKS(Java Keystore 형식)임을 선언합니다.
file
속성은 키 항목에 클라이언트의 X.509 인증서 체인 및 개인 키가 포함된 키 저장소 파일 wibble.jks
. password
속성은 키 저장소의 콘텐츠에 액세스하는 데 필요한 키 저장소 암호를 지정합니다.
키 저장소 파일에는 하나의 키 항목이 포함되어 있으므로 항목을 식별하기 위해 키 별칭을 지정할 필요가 없습니다. 그러나 여러 키 항목이 있는 키 저장소 파일을 배포하는 경우 다음과 같이 sec:certAlias
요소를 http:tlsClientParameters
요소의 자식으로 추가하여 이 경우 키를 지정할 수 있습니다.
<http:tlsClientParameters>
...
<sec:certAlias>CertAlias</sec:certAlias>
...
</http:tlsClientParameters>
키 저장소 파일을 생성하는 방법에 대한 자세한 내용은 2.5.3절. “CA를 사용하여 Java 키 저장소에서 서명된 인증서 생성” 을 참조하십시오.
file
속성 대신 resource
속성(클래스 경로에 키 저장소 파일이 제공됨) 또는 url
특성을 사용하여 키 저장소의 위치를 지정할 수 있습니다. 특히 리소스
속성은 OSGi 컨테이너에 배포된 애플리케이션과 함께 사용해야 합니다. 신뢰할 수 없는 출처에서 신뢰 저장소를 로드하지 않도록 주의해야 합니다.
1.7. HTTPS 서버 구성
클라이언트가 X.509 인증서를 제공해야 하는 보안 HTTPS 서버를 고려해 보십시오. 예 1.5. “샘플 HTTPS 서버 구성” 이러한 서버를 구성하는 방법을 보여줍니다.
예 1.5. 샘플 HTTPS 서버 구성
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xsi:schemaLocation="..."> <httpj:engine-factory bus="cxf"> <httpj:engine port="9001"> <httpj:tlsServerParameters secureSocketProtocol="TLSv1"> <sec:keyManagers keyPassword="password"> <sec:keyStore type="JKS" password="password" file="certs/cherry.jks"/> </sec:keyManagers> <sec:trustManagers> <sec:keyStore type="JKS" password="password" file="certs/truststore.jks"/> </sec:trustManagers> <sec:cipherSuitesFilter> <sec:include>.*_WITH_3DES_.*</sec:include> <sec:include>.*_WITH_DES_.*</sec:include> <sec:exclude>.*_WITH_NULL_.*</sec:exclude> <sec:exclude>.*_DH_anon_.*</sec:exclude> </sec:cipherSuitesFilter> <sec:clientAuthentication want="true" required="true"/> </httpj:tlsServerParameters> </httpj:engine> </httpj:engine-factory> </beans>
이전 서버 구성은 다음과 같이 설명되어 있습니다.
bus
속성은 관련 CXF Bus 인스턴스를 참조합니다. 기본적으로 ID가 cxf
인 CXF 버스 인스턴스는 Apache CXF 런타임에서 자동으로 생성됩니다.
서버 측에서 TLS는 각 WSDL 포트에 대해 구성되지 않습니다. 각 WSDL 포트를 구성하는 대신 TLS 보안 설정은 특정 TCP 포트에 적용되며 이 예에서는 9001
입니다. 따라서 이 TCP 포트를 공유하는 모든 WSDL 포트는 동일한 TLS 보안 설정으로 구성됩니다.
http:tlsServerParameters 요소에는 서버의 모든 TLS 구성 세부 정보가 포함됩니다.
sec:keyManagers
요소는 X.509 인증서와 개인 키를 서버에 연결하는 데 사용됩니다. keyPasswod
속성에 의해 지정된 암호는 인증서의 개인 키를 해독하는 데 사용됩니다.
sec:keyStore
요소는 X.509 인증서와 Java 키 저장소에 저장된 개인 키를 지정하는 데 사용됩니다. 이 샘플은 키 저장소가 JKS(Java Keystore 형식)임을 선언합니다.
file
속성은 키 항목에 클라이언트의 X.509 인증서 체인과 개인 키가 포함된 키 저장소 파일 cherry.jks
를 지정합니다. password
속성은 키 저장소의 콘텐츠에 액세스하는 데 필요한 키 저장소 암호를 지정합니다.
키 저장소 파일에는 하나의 키 항목이 포함되어 있으므로 항목을 식별하기 위해 키 별칭을 지정할 필요가 없습니다. 그러나 여러 키 항목이 있는 키 저장소 파일을 배포하는 경우 다음과 같이 sec:certAlias
요소를 http:tlsClientParameters
요소의 자식으로 추가하여 이 경우 키를 지정할 수 있습니다.
<http:tlsClientParameters>
...
<sec:certAlias>CertAlias</sec:certAlias>
...
</http:tlsClientParameters>
file
속성 대신 resource
속성 또는 url
속성을 사용하여 키 저장소의 위치를 지정할 수 있습니다. 신뢰할 수 없는 출처에서 신뢰 저장소를 로드하지 않도록 주의해야 합니다.
이러한 키 저장소 파일을 생성하는 방법에 대한 자세한 내용은 2.5.3절. “CA를 사용하여 Java 키 저장소에서 서명된 인증서 생성” 을 참조하십시오.
sec:trustManagers
요소는 신뢰할 수 있는 CA 인증서 목록을 지정하는 데 사용됩니다(서버는 이 목록을 사용하여 클라이언트에서 제공하는 인증서를 신뢰 여부를 결정합니다).
sec:keyStore
요소의 file
속성은 하나 이상의 신뢰할 수 있는 CA 인증서를 포함하는 Java 키 저장소 파일 truststore.jks
를 지정합니다. password
속성은 키 저장소인 truststore.jks
에 액세스하는 데 필요한 암호를 지정합니다. 3.2.2절. “HTTPS를 위한 신뢰할 수 있는 CA 인증서 지정”을 참조하십시오.
file
속성 대신 resource
속성 또는 url
속성을 사용하여 키 저장소의 위치를 지정할 수 있습니다.
sec:cipherSuitesFilter
요소는 서버가 TLS 연결에 사용할 암호화 제품군의 선택을 좁히는 데 사용할 수 있습니다. 자세한 내용은 4장. HTTPS Cipher Suites 구성 을 참조하십시오.
sec:clientAuthentication
요소는 클라이언트 인증서의 프레젠테이션에 대한 서버의 disposition를 결정합니다. 요소에는 다음과 같은 속성이 있습니다.
-
want
attribute-Iftrue
(기본값) 서버는 TLS 핸드셰이크 중에 X.509 인증서를 제공하도록 클라이언트를 요청합니다.false
인 경우 서버에서 X.509 인증서를 제공하도록 클라이언트를 요청하지 않습니다. -
required
attribute-Iftrue
, 서버는 클라이언트가 TLS 핸드셰이크 중에 X.509 인증서를 제공하지 못하는 경우 예외를 발생시킵니다.false
(기본값)인 경우 클라이언트가 X.509 인증서를 제공하지 않으면 예외가 발생하지 않습니다.