제17장 웹 서비스 보안

내용 목차

17.1. 개요
17.2. 전송 수준 보안
17.3. 메시지 수준 보안
17.3.1. 웹 서비스 보안 정책
17.3.2. 웹 서비스 보안
17.3.3. 웹 서비스 보안 대화
17.3.4. 웹 서비스 신뢰
17.4. 메시지 수준 보안 설정
17.4.1. 공통 설정
17.4.2. 사용자명 인증을 통한 대칭 바인딩의 인증 기능 강화
17.4.3. 상호 인증 보안
17.4.4. SSL을 통한 SAML 인증
17.4.5. 보안 대화
17.4.6. 웹 서비스 신뢰
17.4.7. 실행
17.5. JAX-RPC(JEUS 5) 웹 서비스 보안 이전 방법
17.5.1. 암호화
17.5.2. 서명
17.5.3. Timestamp
17.5.4. 사용자명 토큰
17.6. 접근 제어 설정된 웹 서비스 호출 방법
17.6.1. Portable Artifact 생성
17.6.2. 웹 서비스의 클라이언트 작성

본 장에서는 전송 수준과 메시지 수준의 웹 서비스 보안에 대해 자세히 설명하고, JEUS 웹 서비스에서 이러한 보안을 적용하는 방법에 대해 설명한다.

웹 서비스에 보안을 적용하기 위해서는 전통적으로 다음과 같은 2가지 방식이 존재한다.

웹 서비스의 전송 수준 보안(Transport-level Security)은 웹 서비스 클라이언트 응용 프로그램과 웹 서비스 간의 연결을 SSL을 사용하여 안전하게 하는 것을 의미한다.

전체적인 절차는 다음과 같다.

  1. JEUS 서버의 SSL을 설정한다.

    웹 서비스 개발 부분은 추가 작업이 필요하지 않다. JEUS 서버에서의 SSL 설정은 "JEUS Web Engine 안내서"를 참조한다.

  2. 다음의 과정으로 클라이언트 응용 프로그램의 SSL을 설정한다.

    1. 인증서를 가져온다(Internet Explorer 등을 통해 인증서를 로컬 디렉터리에 저장한다).

    2. 가져온 인증서를 Keystore에 저장한다.

    3. wsimport를 사용하여 WSDL로부터 Stub을 생성하려고 하거나 클라이언트에서 웹 서비스를 호출하기 위해 클라이언트를 실행할 때 시스템 프로퍼티 값을 다음과 같이 설정한다.

      –Djavax.net.ssl.trustStore=keystore_name
      –Djavax.net.ssl.trustStorePassword=keystore_password
    4. wsimport 툴을 사용하기 위해 추가적으로 다음과 같은 환경변수 설정이 필요하다.

      set WSIMPORT_OPTS=-Djavax.net.ssl.trustStore=keystore_name 
            -Djavax.net.ssl.trustStorePassword=keystore_password

다음은 JEUS 웹 서비스가 구현하고 있는 웹 서비스 보안에 관한 명세서이다.

본 절에서는 각각의 명세서들에 대해 그 의미와 시나리오에 대해 설명한다.

웹 서비스 보안(WS-Security) 명세는 메시지의 XML 서명을 사용한 데이터 무결성과 XML 암호화를 사용한 데이터 비밀성 2가지를 실현하여 안전한 웹 서비스를 구현할 때 사용되는 확장된 SOAPElement들을 정의하고 있다.

다음은 웹 서비스 보안 명세를 사용한 웹 서비스 보안 시나리오이다.

  • 사용자명 인증(Username Authentication)을 통한 대칭 바인딩의 인증 기능 강화

  • 상호 인증 보안(Mutual Certificates Security)

  • SSL을 통한 SAML(Security Assertions Mark-up Language) 인증

이 예제는 대칭 바인딩(Symmetric Binding)을 통한 메시지 보안 예제이다. 앞서 설명한 것과 마찬가지로 대칭 바인딩에서는 클라이언트와 서버가 암호화 키와 서명에 동일한 인증서 정보를 사용한다. 이 예제에서는 그 인증서 정보로써 서버의 인증서를 사용한다. 이때 클라이언트는 자신이 누구인지를 서버에 인증받을 방법이 별도로 존재하지 않기 때문에 부가적으로 사용자명 토큰을 사용한다.

다음은 사용자명 인증(Username Authentication)의 시나리오와 Keystore 설정에 대한 설명이다.

  • 시나리오

    다음은 사용자명 인증의 시나리오이다.

    1. 클라이언트는 대칭 키를 생성한 후 이를 사용해 요청 메시지를 암호화 및 서명을 한다. 이때 서버의 공개 키를 사용하여 대칭 키를 함께 메시지에 담아 보낸다. 추가적으로 사용자명과 비밀번호 정보를 함께 보낸다.

    2. 서버는 서버의 개인 키를 사용하여 대칭 키를 해독한 뒤 이를 사용하여 클라이언트의 요청 메시지를 복호화하고 서명을 검증한다. 추가적으로 사용자명과 비밀번호를 통해 클라이언트를 인증한다.

    3. 서버는 다시 그 대칭 키를 통해 응답 메시지를 서명 및 암호화한다. 이때 대칭 키를 별도로 클라이언트로 전송하지는 않는다.

    4. 클라이언트는 가지고 있던 대칭 키를 사용하여 서버의 응답 메시지를 해석하고 서명을 확인한다.

  • Keystore 설정

    다음은 Keystore 설정 정보이다.

    구분설명
    클라이언트서버의 공개 키가 담긴 Keystore이다.
    서버서버의 개인 키가 담긴 Keystore이다.

이 예제는 비대칭 바인딩, 상호 인증서를 통한 메시지 보안 예제이다. 대칭 바인딩과 달리 비대칭 바인딩에서는 클라이언트와 서버가 암호화 키와 서명에 서로 다른 인증서 정보를 사용한다. 서로 자신의 개인 키로 서명을 하고 인증서 정보를 넘겨줌으로써 서로 서명을 검증할 때 상대편이 누구인지를 인증할 수 있다.

다음은 상호 인증 보안 시나리오와 Keystore 설정에 대한 설명이다.

  • 시나리오

    다음은 상호 인증 보안(Mutual Certificates Security)의 시나리오이다.

    1. 클라이언트는 클라이언트의 개인 키로 메시지에 서명을 하고 하나의 대칭 키를 생성해서 메시지를 암호화한 후, 그 대칭 키를 서버의 공개 키를 사용하여 암호화하여 메시지와 함께 서버에게 요청 메시지를 보낸다. 이때 인증 역할을 하게 될 클라이언트의 인증서를 함께 보낸다.

    2. 서버는 서버의 개인 키를 사용하여 대칭 키를 꺼낸 후 암호화된 메시지를 해석한다. 인증서를 통해 인증을 하고 클라이언트의 공개 키로 서명을 검증한다.

    3. 서버는 서버의 개인 키로 메시지에 서명을 하고 하나의 대칭 키를 생성해서 메시지를 암호화한 후 그 대칭 키를 클라이언트의 공개 키를 사용하여 암호화하며 메시지와 함께 클라이언트에게 응답 메시지를 보낸다. 이때 인증 역할을 하게 될 서버의 인증서는 함께 보내지 않는다.

    4. 클라이언트는 클라이언트의 개인 키를 사용하여 대칭 키를 꺼낸후 암호화된 메시지를 해석한다. 서버의 공개 키로 서명을 확인한다.

  • Keystore 설정

    다음은 Keystore 설정 정보이다.

    구분설명
    클라이언트서버의 공개 키가 담긴 Keystore이다.
    서버서버의 개인 키가 담긴 Keystore이다.

본 절에서는 SAML(Security Assertions Mark-up Language) 토큰을 SOAP 메시지 헤더에 포함시켜 보내는 방법에 대해 설명한다.

실제 웹 서비스에서 SAML 토큰을 사용한 서비스를 하려면 이러한 SAML 토큰을 생성하는 SAML 토큰 프레임워크가 필요하다. 여기서는 단순히 핸들러를 통해 SAML 토큰을 텍스트로 생성해서 보내는 예를 통해 어떻게 SAML 토큰을 SOAP 메시지 헤더에 포함시키는지에 대해 알 수 있다.

웹 서비스의 발전과 사용자의 활용 빈도가 높아짐에 따라 다양한 웹 애플리케이션 간에 보안 및 인증 정보를 교환할 필요성이 높아지고 이에 따른 교환 표준이 필요하다. 이와 같은 표준을 제공하기 위해 탄생한 언어가 SAML이다.

SAML은 다음과 같은 기능을 제공한다.

  • 사용자 보안 정보에 대한 XML 포맷을 제공하고 이러한 정보를 요청 및 전송하기 위한 포맷을 제공한다.

  • SOAP과 같은 프로토콜에서 이러한 메시지를 사용하는 방법을 정의한다.

  • 웹 SSO와 같이 일반적인 특정 사용 사례에 대해 자세한 메시지 교환 방법을 지정한다.

  • 사용자의 신원을 Export시키지 않고 사용자 속성을 결정하는 기능을 비롯하여 여러 가지 개인 정보 보호 메커니즘을 지원한다.

  • UNIX, Microsoft Windows, X.509, LDAP, DCE, XCML 등 널리 사용되는 기술에서 제공하는 포맷으로 ID 정보를 처리하는 방법을 제공한다.

  • 메타 데이터 스키마를 수식화하여 참여하는 시스템에서 지원하는 SAML 옵션과 통신할 수 있는 기능을 제공한다.

다음은 SSL을 통한 SAML 인증을 사용하기 위한 시나리오이다.

  • 시나리오

    1. 클라이언트는 SAML 토큰을 SOAP 메시지 헤더에 포함하여 SSL 설정을 통해 메시지를 보낸다.

    2. 서버는 SOAP 메시지 헤더에 포함된 SAML 토큰을 해석하고 응답 메시지를 보낸다.

참고

모든 클라이언트와 서버의 메시지 교환은 JEUS 서버의 SSL 설정을 통해 이루어진다.

웹 서비스 보안 대화(Web Service Secure Conversation) 명세는 서비스 제공자와 클라이언트 간의 보안 컨텍스트 생성 및 공유를 정의한다. 보안 컨텍스트는 메시지를 교환할 때 생기는 간접비용(overhead)을 줄이기 위해 사용된다. 이 명세는 보다 나은 메시지 수준의 보안과 보다 효율적인 다중 메시지 교환을 제공하기 위한 표준을 정의한다.

이 명세를 따르고 있는 JEUS 웹 서비스는 다중 메시지 교환을 위한 보안 방식이 정의되는 기본 메커니즘을 제공하고 더욱 더 효율적인 키나 새로운 키 재료와 함께 컨텍스트가 수립되도록 한다. 이러한 접근은 전체적인 성능과 다음에 따르는 메시지 교환의 보안성을 향상시킨다.

대칭 바인딩에서는 메시지를 여러 번 주고받을 때마다 암호화 키를 매번 생성해야 한다. 따라서 메시지를 여러 번 주고받는 시나리오에서는 적합하지 않다. 이 예제에서는 보안 대화(Secure Conversation)를 통해 첫 메시지를 주고받기 전 Handshaking 과정을 통해 비대칭 바인딩으로 서로 SecureContext를 수립하고 이후 실제 메시지를 여러 번 주고받을 때는 수립한 SecureContext를 사용하여 대칭 바인딩과 같이 서명과 암호화에 사용하게 된다. 인증 과정은 처음 비대칭 바인딩을 통한 SecureContext 수립 과정에서 거치게 된다.

다음은 웹 서비스 보안 대화의 시나리오와 Keystore 설정에 대한 설명이다.

  • 시나리오

    다음은 웹 서비스 보안 대화의 시나리오이다.

    1. 클라이언트는 자신의 인증서와 SecureContext 정보를 자신의 인증서를 사용해서 서명하고, 서버의 공개 키로 암호화하여 서버에 전송한다(비대칭 바인딩).

    2. 서버는 자신의 개인 키로 클라이언트의 메시지를 복호화하고 클라이언트 서명을 검증하면서 인증 절차를 거친후 SecureContext 수립 메시지로 응답한다(비대칭 바인딩).

    3. 이후 클라이언트와 서버는 메시지를 주고받을 때 이 SecureContext 정보를 통해 암호화 및 서명을 한다(대칭 바인딩).

  • Keystore 설정

    다음은 Keystore 설정 정보이다.

    구분설명
    클라이언트클라이언트의 개인 키와 서버의 공개 키가 담긴 Keystore이다.
    서버서버의 개인 키와 클라이언트의 공개 키가 담긴 Keystore이다.

본 절에서는 WS-Trust를 인증에 관해 사용하는 예에 대해 살펴본다. 서로 다른 토큰, 즉 신뢰할 수 없는 관계의 인증서는 STS를 통해 SAML 토큰이라는 다른 형태로 변환되어 요청자를 신뢰할 수 없는 응답자가 STS를 통해 인증할 수 있다.

웹 서비스 보안을 사용하는 메시지 교환 방식에서는 서비스와 클라이언트 간에 보안 정보 공유를 위해 사용되는 보안 토큰에 대해 이미 합의되어야 하지만, 이러한 사전 합의가 이루어지지 않는 경우 메시지 교환 이전에 신뢰 관계(Trust Relationship)가 성립되어야 한다. 이러한 것을 웹 서비스 신뢰(Web Service Trust)라고 하며 JEUS 웹 서비스는 이를 지원하고 있다.

웹 서비스 신뢰는 서버와 클라이언트가 서로 다른 형태의 보안 토큰 또는 서로 다른 도메인의 보안 토큰을 사용해서 서로를 인증하지 못하는 상황일 때 사용할 수 있다. 이러한 클라이언트와 서버의 상이한 보안 토큰때문에 서로를 인증하지 못하는 상황은 클라이언트와 서버 사이에 각각의 인증 역할을 중계해 주는 또 다른 웹 서비스가 존재하여 해결한다. 이러한 웹 서비스를 통상적으로 STS(Security Token Service)라고 한다.

웹 서비스 신뢰는 다음의 관계를 갖는다.

  • 클라이언트와 서버는 서로 직접적인 신뢰 관계가 없다.

  • 클라이언트와 STS는 서로 신뢰 관계가 있다.

  • STS와 서버는 서로 신뢰 관계가 있다.

다음 그림과 같이 Requestor는 웹 서비스와 통신하기 전에 웹 서비스가 자신을 인증할 수 있도록 하는 보안 토큰을 STS로부터 동적으로 부여받는다. 부여받은 보안 토큰을 통해 Requestor는 웹 서비스에게 실제로 보내려는 메시지에 STS로 부여받은 보안 토큰을 함께 실어 보내게 되며 웹 서비스는 Requestor를 인증(신뢰)할 수 있다.


(출처: http://docs.oasis-open.org/ws-sx/ws-trust/200512/ws-trust-1.3-os.html)

다음은 웹 서비스 신뢰 시나리오와 Keystore 설정에 대한 설명이다.

  • 시나리오

    다음은 웹 서비스 신뢰의 시나리오이다.

    1. 클라이언트는 자신의 인증서, 사용자명, 암호와 함께 실제 메시지를 전달할 서버에 대한 SAML 인증서 발급을 STS에 요청한다.

    2. STS는 클라이언트를 인증한 후 SAML 인증서를 발급한다.

    3. 클라이언트는 SAML 인증서와 함께 서버에 메시지를 보낸다.

    4. 서버는 SAML 인증서를 통해 클라이언트를 신뢰하고 비즈니스 로직을 수행한다.

  • Keystore 설정

    다음은 Keystore 설정 정보이다.

    구분설명
    클라이언트

    - 클라이언트의 개인 키와 서버의 공개 키가 담긴 Keystore이다.

    - 클라이언트의 개인 키와 STS 서버의 공개 키가 담긴 Keystore이다.

    서버서버의 개인 키와 클라이언트의 공개 키가 담긴 Keystore이다.
    STS 서버서버의 개인 키와 클라이언트의 공개 키가 담긴 Keystore이다.

본 절에서는 JEUS 웹 서비스 메시지 수준 보안의 여러 가지 시나리오 예제에서 공통적으로 적용되는 설정법과 각각의 시나리오에 대한 설정법을 자세히 살펴볼 것이다. 실제 여러 가지 시나리오 예제에서 동작하는 것에 대해서는 샘플을 참고한다.

참고

각 시나리오별 메시지 보안 설정 예제의 웹 서비스와 클라이언트의 비즈니스 로직은 모두 동일하다.

JEUS 웹 서비스 메시지 수준 보안의 여러 가지 시나리오 예제에서 공통적으로 적용되는 설정은 서버와 클라이언트로 구분하여 설정한다.

다음은 'endpoint-policy-subject', 'operation-policy-subject', 'input(output)-message-policy-subject'에 공통적으로 들어가는 보안 설정들에 대한 설명이다.

Java 클래스로부터 웹 서비스 구현

Java 클래스로부터 웹 서비스 메시지 보안을 구현하기 위해서는 다음과 같이 wsgen 툴의 -policy 기능을 사용하여 웹 서비스를 구성한다.

$ wsgen fromjava.server.AddNumbersImpl -d web/WEB-INF -policy service-config.xml

-policy의 인자로 사용되는 service-config.xml을 구성하려면 service-config.xml을 위한 JEUS 보안 정책 스키마인 jeus-webservices-config.xsd에 대한 지식이 필요하다.

JEUS 보안 정책 스키마는 다음과 같이 'endpoint-policy-subject', 'operation-policy-subject', 'input(output)-message-policy-subject' element에 보안 설정을 할 수 있다.

[예 17.3] 서버 Java 클래스 메시지 수준 보안 설정 (1) : << jeus-webservices-config.xsd >>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns="http://www.tmaxsoft.com/xml/ns/jeus"
targetNamespace="http://www.tmaxsoft.com/xml/ns/jeus"
xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
attributeFormDefault="unqualified" version="7.0">
    ......
    <xs:element name="web-services-config" type="web-services-configType" />
    <xs:complexType name="web-services-configType">
        <xs:choice>
            ......
            <xs:element name="policy" type="policy-configType"
            maxOccurs="unbounded" />
        </xs:choice>
    </xs:complexType>
    <xs:complexType name="policy-configType">
        <xs:sequence>
            <xs:element name="endpoint-policy-subject"
            type="endpointPolicySubjectType" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="endpointPolicySubjectType">
        <xs:sequence>
            ......
            <xs:element name="security-policy"
            type="endpointSecurityPolicyType" minOccurs="0" />
            <xs:element name="operation-policy-subject"
            type="operationPolicySubjectType" minOccurs="0"
            maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="operationPolicySubjectType">
        <xs:sequence>
            <xs:element name="security-policy"
            type="operationSecurityPolicyType" minOccurs="0" />
            ......
            <xs:element name="input-message-policy-subject"
            type="messagePolicySubjectType" minOccurs="0" />
            <xs:element name="output-message-policy-subject"
            type="messagePolicySubjectType" minOccurs="0" />
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="messagePolicySubjectType">
        <xs:sequence>
            <xs:element name="security-policy" type="messageSecurityPolicyType"
            minOccurs="0" />
        </xs:sequence>
    </xs:complexType>
    ......
</xs:schema>

이 3가지 element들의 보안 설정 내용은 다음과 같다.

WSDL로부터 웹 서비스 구현

WSDL로부터 구현하기 위해서는 WSDL 문서에 직접 메시지 보안 정책 설정을 하고 wsimport 툴을 사용하여 웹 서비스를 구성한다. WSDL로부터 구현하려면 WS-Policy의 하부 스펙인 WS-SecurityPolicy의 내용을 정확하게 이해하여 WSDL에 적용하면 간단히 웹 서비스 메시지 보안을 구현할 수 있다.

다음은 메시지 보안이 설정된 웹 서비스를 구현하기 위한 WSDL 예이다. Keystore에 대한 설정은 절대 경로 또는 상대 경로를 포함한 실제 Keystore 파일의 위치를 지정한다. 상대 경로로 지정할 때는 서비스 구현 클래스가 포함된 classes 디렉터리 하위의 META-INF 디렉터리에 Keystore 파일이 위치해야 한다.

[예 17.13] WSDL 메시지 수준 보안 설정 : << jeus-webservices-config.xsd >>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions
...
targetNamespace="http://tmax.com/" name="NewWebServiceService">
<ns1:Policy xmlns:ns1="http://schemas.xmlsoap.org/ws/2004/09/policy"
 wsu:Id="NewWebServicePortBindingPolicy">
  <ns1:ExactlyOne>
    <ns1:All>
      <ns7:SymmetricBindingxmlns:ns7="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <ns1:Policy>
            <ns1:ExactlyOne>
              <ns1:All>
                <ns7:AlgorithmSuite>
                  <ns1:Policy>
                    <ns1:ExactlyOne>
                      <ns1:All>
                        <ns7:TripleDes />
                      </ns1:All>
                    </ns1:ExactlyOne>
                  </ns1:Policy>
                </ns7:AlgorithmSuite>
                <ns7:IncludeTimestamp />
                <ns7:Layout>
                  <ns1:Policy>
                    <ns1:ExactlyOne>
                      <ns1:All>
                        <ns7:Strict />
                      </ns1:All>
                    </ns1:ExactlyOne>
                  </ns1:Policy>
                </ns7:Layout>
                <ns7:OnlySignEntireHeadersAndBody />
                <ns7:ProtectionToken>
                  <ns1:Policy>
                    <ns1:ExactlyOne>
                      <ns1:All>
                        <ns7:X509Tokenns7:IncludeToken=
            "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never">
                          <ns1:Policy>
                            <ns1:ExactlyOne>
                              <ns1:All>
                              <ns7:WssX509V3Token10/>
                              </ns1:All>
                            </ns1:ExactlyOne>
                          </ns1:Policy>
                        </ns7:X509Token>
                      </ns1:All>
                    </ns1:ExactlyOne>
                  </ns1:Policy>
                </ns7:ProtectionToken>
              </ns1:All>
            </ns1:ExactlyOne>
          </ns1:Policy>
      </ns7:SymmetricBinding>
      <ns8:Wss11xmlns:ns8="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
          <ns1:Policy>
              <ns1:ExactlyOne>
                  <ns1:All>
                      <ns8:MustSupportRefEncryptedKey />
                      <ns8:MustSupportRefIssuerSerial />
                      <ns8:MustSupportRefThumbprint />
                  </ns1:All>
              </ns1:ExactlyOne>
          </ns1:Policy>
      </ns8:Wss11>
      <sc:KeyStore wspp:visibility="private"
      alias="xws-security-server"
      storepass="changeit" type="JKS"
      location="keystore.jks" />
      <sc:TrustStore wspp:visibility="private"
      peeralias="xws-security-client"
      storepass="changeit" type="JKS"
      location="cacerts.jks" />
      <sc:ValidatorConfigurationxmlns:sc=
            "http://schemas.sun.com/2006/03/wss/server">
        <sc:Validator name="usernameValidator" 
             classname="com.tmax.UsernamePasswordValidator" />
      </sc:ValidatorConfiguration>
      <ns9:UsingAddressingxmlns:ns9="http://www.w3.org/2006/05/addressing/wsdl" />
    </ns1:All>
  </ns1:ExactlyOne>
</ns1:Policy>
<ns10:Policy xmlns:ns10="http://schemas.xmlsoap.org/ws/2004/09/policy" 
       wsu:Id="NewWebServicePortBinding_add_Input_Policy">
  <ns10:ExactlyOne>
    <ns10:All>
      <ns11:EncryptedPartsxmlns:ns11=
           "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
        <ns11:Body />
      </ns11:EncryptedParts>
      <ns12:SignedPartsxmlns:ns12=
           "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
        <ns12:Body />
        <ns12:Header Name="ReplyTo"
            Namespace="http://www.w3.org/2005/08/addressing" />
        <ns12:HeaderNamespace="http://www.w3.org/2005/08/addressing" Name="To"/>
        <ns12:Header Name="From" 
            Namespace="http://www.w3.org/2005/08/addressing"/>
        <ns12:Header Name="MessageId" 
            Namespace="http://www.w3.org/2005/08/addressing"/>
        <ns12:Header Name="FaultTo" 
            Namespace="http://www.w3.org/2005/08/addressing"/>
        <ns12:Header Name="Action" 
            Namespace="http://www.w3.org/2005/08/addressing"/>
        <ns12:Header Name="RelatesTo" 
            Namespace="http://www.w3.org/2005/08/addressing"/>
      </ns12:SignedParts>
      <ns13:SignedSupportingTokensxmlns:ns13=
         "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
        <ns10:Policy>
          <ns10:ExactlyOne>
            <ns10:All>
             <ns13:UsernameToken ns13:
               IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/
               IncludeToken/AlwaysToRecipient">
               <ns10:Policy>
                 <ns10:ExactlyOne>
                   <ns10:All>
                   <ns13:WssUsernameToken10/>
                   </ns10:All>
                 </ns10:ExactlyOne>
               </ns10:Policy>
             </ns13:UsernameToken>
            </ns10:All>
          </ns10:ExactlyOne>
        </ns10:Policy>
      </ns13:SignedSupportingTokens>
    </ns10:All>
  </ns10:ExactlyOne>
</ns10:Policy>
<ns14:Policy xmlns:ns14="http://schemas.xmlsoap.org/ws/2004/09/policy"
  wsu:Id="NewWebServicePortBinding_add_Output_Policy">
  <ns14:ExactlyOne>
    <ns14:All>
      <ns15:EncryptedPartsxmlns:ns15="http://schemas.xmlsoap.org/ws/
        2005/07/securitypolicy">
        <ns15:Body />
      </ns15:EncryptedParts>
      <ns16:SignedPartsxmlns:ns16="http://schemas.xmlsoap.org/ws/
        2005/07/securitypolicy">
        <ns16:Body />
        <ns16:Header Name="ReplyTo"
              Namespace="http://www.w3.org/2005/08/addressing"/>
        <ns16:HeaderNamespace="http://www.w3.org/2005/08/addressing" 
              Name="To"/>
        <ns16:Header Name="From" 
              Namespace="http://www.w3.org/2005/08/addressing"/>
        <ns16:Header Name="MessageId" 
              Namespace="http://www.w3.org/2005/08/addressing"/>
        <ns16:Header Name="FaultTo" 
              Namespace="http://www.w3.org/2005/08/addressing"/>
        <ns16:Header Name="Action" 
              Namespace="http://www.w3.org/2005/08/addressing"/>
        <ns16:Header Name="RelatesTo" 
              Namespace="http://www.w3.org/2005/08/addressing"/>
      </ns16:SignedParts>
    </ns14:All>
  </ns14:ExactlyOne>
</ns14:Policy>
<types>
    ...
</types>
<message name="add">
    ...
</message>
<portType name="NewWebService">
    ...
</portType>
<binding name="NewWebServicePortBinding" type="tns:NewWebService">
  <ns17:PolicyReferencexmlns:ns17="http://schemas.xmlsoap.org/ws/2004/09/policy" 
       URI="#NewWebServicePortBindingPolicy" />
  <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
  <operation name="add">
    <soap:operation soapAction="" />
    <input>
      <ns18:PolicyReferencexmlns:ns18="http://schemas.xmlsoap.org/ws/2004/09/policy" 
          URI="#NewWebServicePortBinding_add_Input_Policy" />
      <soap:body use="literal" />
    </input>
    <output>
      <ns19:PolicyReferencexmlns:ns19="http://schemas.xmlsoap.org/ws/2004/09/policy"
         URI="#NewWebServicePortBinding_add_Output_Policy" />
      <soap:body use="literal" />
    </output>
  </operation>
</binding>
<service name="NewWebServiceService">
 <port name="NewWebServicePort" binding="tns:NewWebServicePortBinding">
   <soap:addresslocation="http://localhost:8088/usernameAuthentication_war/
   NewWebServiceService"/>
 </port>
 </service>
</definitions>

메시지 보안이 설정된 웹 서비스의 클라이언트는 wsit-client.xml 파일을 통해 다음과 같이 부가적으로 Keystore 및 Callback 핸들러 등을 설정해야 한다. 그 밖의 다른 메시지 보안 설정은 서버의 WSDL에 설정된 메시지 보안 정책을 런타임에 해석하여 메시지 보안 환경을 자동으로 구성한다.

Keystore에 대한 설정은 절대 경로 또는 상대 경로를 포함한 실제 Keystore 파일의 위치를 지정한다. 상대 경로로 지정할 때는 서비스 구현 클래스가 포함된 classes 디렉터리 하위의 META-INF 디렉터리에 Keystore 파일이 위치해야 한다.

[예 17.14] 클라이언트 메시지 수준 보안 설정 : << jeus-webservices-config.xsd >>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
...
targetNamespace="http://server.fromjava/">
  <wsp:UsingPolicy />
    <wsp:Policy wsu:Id="TmaxBP0">
        <wsp:ExactlyOne>
            <wsp:All>
                <CallbackHandlerConfiguration
                xmlns="http://schemas.sun.com/2006/03/wss/client">
                    <CallbackHandler default="user_jeus" name="usernameHandler" />
                    <CallbackHandler default="password_jeus"
                    name="passwordHandler" />
                </CallbackHandlerConfiguration>
                <TrustStore location="cacerts.jks" peeralias="xws-security-server"
                storepass="changeit" type="JKS"
                xmlns:ns0="http://java.sun.com/xml/ns/wsit/policy"
                ns0:visibility="private"
                xmlns="http://schemas.sun.com/2006/03/wss/client" />
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
    <types>
        ...
    </types>
    <message name="addNumbers">
        ...
    </message>
    <portType name="AddNumbersImpl">
        ...
    </portType>
    <binding name="AddNumbersImplPortBinding" type="tns:AddNumbersImpl">
        <wsp:PolicyReference URI="#TmaxBP0" />
        <soap:binding style="document"
        transport="http://schemas.xmlsoap.org/soap/http" />
        <operation name="addNumbers">
            <soap:operation soapAction="" />
            <input>
                <soap:body use="literal" />
            </input>
            <output>
                <soap:body use="literal" />
            </output>
        </operation>
    </binding>
    <service name="AddNumbersImplService">
        <port binding="tns:AddNumbersImplPortBinding" name="AddNumbersImplPort">
            <soap:address
location="http://localhost:8088/DocLitEchoService/AddNumbersImplService" />
        </port>
    </service>
</definitions>

본 절에서는 서버와 클라이언트에서 사용자명 인증을 통한 대칭 바인딩의 인증 기능 강화 방법에 대해서 설명한다.

서버 웹 서비스의 설정은 service-config.xml 파일을 작성하고 사용자명의 유효자(Validator) 클래스를 작성한다.

웹 서비스 설정 파일 작성

다음은 웹 서비스 설정 파일 작성에 대한 예이다.


사용자명의 유효자(Validator) 클래스 작성

com.sun.xml.wss.impl.callback.PasswordValidationCallback.PasswordValidator을 구현하여 username token을 사용해서 접근한 사용자의 username과 password를 validate한다.


클라이언트 웹 서비스의 설정은 추가적으로 wsit-client.xml에 Keystore(Truststore) 설정과 함께 사용자명 핸들러를 설정해야 한다.

Keystore(Truststore) 설정 및 사용자명 핸들러의 설정

wsit-client.xml 파일에 다음과 같이 설정한다.


사용자명 핸들러 클래스 작성

javax.security.auth.callback.CallbackHandler을 구현하여 각각의 Callback을 CallbackHandler에 전달하면 여러 가지 설정을 해 줄 수 있다. 전달받은 Callback의 종류에 맞추어 정책에 따른 설정을 한다.

위 예제에서는 NameCallback과 PasswordCallback을 전달받아 Callback에 username과 password를 설정하는 CallbackHandler를 구성한다.

다음의 예제에서는 클래스 파일 내에서 username과 password를 미리 입력해 놓았지만 경우에 따라서 다양한 reader객체를 사용하여 사용자로부터 직접 입력받을 수도 있다.


본 절에서는 서버와 클라이언트에서 상호 인증 보안(Mutual Certificates Security)을 설정하는 방법에 대해 설명한다.

본 절에서는 서버와 클라이언트에서 SSL을 통한 SAML 인증을 설정하는 방법에 대해서 설명한다.

클라이언트의 웹 서비스 설정은 추가적으로 wsit-client.xml에 SAML 메시지 처리를 위한 Callback 핸들러 클래스 설정을 해야 한다.

SAML 메시지 처리를 위한 Callback 핸들러 클래스 설정

wsit-client.xml 파일에 다음과 SAML 메시지 처리를 위한 Callback 핸들러 클래스를 설정한다.


SAML 메시지 처리를 위한 Callback 핸들러 클래스 작성

SAML 표준에 따라 SOAP 요청 메시지에 정보를 담기 위해 예제에서는 javax.security.auth.callback.CallbackHandler를 구현하는 SamlCallbackHandler를 사용한다. SamlCallbackHandler에서는 Callback의 종류에 따라 필요한 assertion을 저장하는 역할을 한다.

다음은 이 예제에서 사용되는 SamlCallbackHandler이다.


본 절에서는 서버와 클라이언트에서 보안 대화(Secure Conversation)를 설정하는 방법에 대해서 설명한다.

클라이언트의 웹 서비스 설정은 추가적으로 wsit-client.xml에 Keystore(Truststore) 설정을 해야 한다.

[예 17.25] 클라이언트 보안 대화 설정 : <<wsit-client.xml>>

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
...
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/">
    <message name="add" />
    <message name="addResponse" />
    <portType name="NewWebService">
        <wsdl:operation name="add">
            <wsdl:input message="tns:add" />
            <wsdl:output message="tns:addResponse" />
        </wsdl:operation>
    </portType>
    <binding name="NewWebServicePortBinding" type="tns:NewWebService">
        <wsp:PolicyReference URI="#NewWebServicePortBindingPolicy" />
        <soap12:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="add">
            <soap12:operation soapAction="http://xmlsoap.org/Ping"
                style="document" />
            <wsdl:input>
                <soap12:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </binding>
    <service name="NewWebServiceService">
        <wsdl:port name="NewWebServicePort" binding="tns:NewWebServicePortBinding">
            <soap12:address location="REPLACE_WITH_ACTUAL_ADDRESS" />
        </wsdl:port>
    </service>
    <wsp:Policy wsu:Id="NewWebServicePortBindingPolicy"
    xmlns:scc="http://schemas.sun.com/ws/2006/05/sc/client">
        <wsp:ExactlyOne>
            <wsp:All>
                <sc:KeyStore wspp:visibility="private"
                    location="./keystore.jks" type="JKS"
                    alias="xws-security-client" storepass="changeit">
                </sc:KeyStore>
                <sc:TrustStore wspp:visibility="private"
                    location="./cacerts.jks" type="JKS"
                    storepass="changeit" peeralias="xws-security-server"
                    stsalias="wssip">
                </sc:TrustStore>
                <scc:SCClientConfiguration wspp:visibility="private">
                    <scc:LifeTime>36000</scc:LifeTime>
                </scc:SCClientConfiguration>
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
</definitions>


본 절에서는 웹 서비스 신뢰(WS-Trust)를 위한 서버와 STS, 클라이언트의 설정 방법에 대해서 설명한다.

STS를 위해 WS-SecurityPolicy 설정을 WSDL의 WS-Policy 프레임워크을 통해 설정해야 한다.

다음은 WS-SecurityPolicy 설정에 대한 예이다.

[예 17.27] WS-SecurityPolicy 설정 : <<sts.wsdl>>

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ...>
    <wsp:Policy wsu:Id="TmaxSTSServerPolicy">
        <wsp:ExactlyOne>
            <wsp:All>
                <sp:SymmetricBinding
                xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:ProtectionToken>
                            <wsp:Policy>
                                <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never">
                                    <wsp:Policy>
                                        <sp:RequireDerivedKeys />
                                        <sp:RequireThumbprintReference />
                                        <sp:WssX509V3Token10 />
                                    </wsp:Policy>
                                </sp:X509Token>
                            </wsp:Policy>
                        </sp:ProtectionToken>
                        <sp:AlgorithmSuite>
                            <wsp:Policy>
                                <sp:Basic128 />
                            </wsp:Policy>
                        </sp:AlgorithmSuite>
                        <sp:Layout>
                            <wsp:Policy>
                                <sp:Lax />
                            </wsp:Policy>
                        </sp:Layout>
                        <sp:IncludeTimestamp />
                        <sp:EncryptSignature />
                        <sp:OnlySignEntireHeadersAndBody />
                    </wsp:Policy>
                </sp:SymmetricBinding>
                <sp:SignedSupportingTokens
                xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                            <wsp:Policy>
                                <sp:WssUsernameToken10 />
                            </wsp:Policy>
                        </sp:UsernameToken>
                    </wsp:Policy>
                </sp:SignedSupportingTokens>
                <sp:Wss11
                xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:MustSupportRefKeyIdentifier />
                        <sp:MustSupportRefIssuerSerial />
                        <sp:MustSupportRefThumbprint />
                        <sp:MustSupportRefEncryptedKey />
                    </wsp:Policy>
                </sp:Wss11>
                <sp:Trust10
                xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:MustSupportIssuedTokens />
                        <sp:RequireClientEntropy />
                        <sp:RequireServerEntropy />
                    </wsp:Policy>
                </sp:Trust10>
                ...
                <sc:ValidatorConfiguration
                    xmlns:sc="http://schemas.sun.com/2006/03/wss/server">
                    <sc:Validator name="usernameValidator"
                        classname="trust.sts.UsernamePasswordValidator" />
                </sc:ValidatorConfiguration>
                <tc:STSConfiguration
                    xmlns:tc="http://schemas.sun.com/ws/2006/05/trust/server"
                    encryptIssuedKey="true" encryptIssuedToken="false">
                    <tc:LifeTime>36000</tc:LifeTime>
                    <tc:Contract>
                    com.sun.xml.ws.security.trust.impl.IssueSamlTokenContractImpl
                    </tc:Contract>
                    <tc:Issuer>TmaxsoftSTS</tc:Issuer>
                    <tc:ServiceProviders>
                       <tc:ServiceProviderendPoint="http://localhost:8088/trust_server/FinancialService">
                            <tc:CertAlias>bob</tc:CertAlias>
                            <tc:TokenType>
                              http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1
                            </tc:TokenType>
                       </tc:ServiceProvider>
                       <tc:ServiceProvider endPoint="default">
                            <tc:CertAlias>bob</tc:CertAlias>
                            <tc:TokenType>
                              http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1
                            </tc:TokenType>
                       </tc:ServiceProvider>
                    </tc:ServiceProviders>
                </tc:STSConfiguration>
                <wsap10:UsingAddressing />
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
    ...
    <wsdl:binding name="ISecurityTokenService_Binding"
        type="tns:ISecurityTokenService">
        <wsp:PolicyReference URI="#TmaxSTSServerPolicy" />
        ...
    </wsdl:binding>
    ...
</wsdl:definitions>


클라이언트의 웹 서비스 설정은 wsit-client.xml에 서버, STS 각각을 위한 Keystore(Truststore) 설정을 해야 한다.

[예 17.28] 클라이언트 웹 서비스 신뢰 설정 : <<wsit-client.xml>>

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://tempuri.org/" ...>
    <!-- FinancialService WSDL -->
    <wsp:Policy wsu:Id="TmaxFSClientPolicy" ...>
        <wsp:ExactlyOne>
            <wsp:All>
                <sc:KeyStore ... />
                <sc:TrustStore  ... />
                <scc:SCClientConfiguration wspp:visibility="private">
                    <scc:LifeTime>36000</scc:LifeTime>
                </scc:SCClientConfiguration>
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
    ...
    <wsdl:binding name="IFinancialService_Binding"
        type="tns:IFinancialService">
        <wsp:PolicyReference URI="#TmaxFSClientPolicy" />
        ...
    </wsdl:binding>
    <wsdl:service name="FinancialService">
        <wsdl:port name="IFinancialService_Port"
            binding="tns:IFinancialService_Binding">
            <soap:address
                location="http://localhost:8088/trust_server/FinancialService" />
        </wsdl:port>
    </wsdl:service>

    <!-- STSService WSDL -->
    <wsp:Policy wsu:Id="TmaxSTSClientPolicy" ...>
        <wsp:ExactlyOne>
            <wsp:All>
                <sc:KeyStore ... />
                <sc:TrustStore ... />
                <sc:CallbackHandlerConfiguration
                    xmlns:sc="http://schemas.sun.com/2006/03/wss/client">
                    <sc:CallbackHandler default="alice" name="usernameHandler" />
                    <sc:CallbackHandler default="alice" name="passwordHandler" />
                </sc:CallbackHandlerConfiguration>
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
    ...
    <wsdl:binding name="ISecurityTokenService_Binding"
        type="tns:ISecurityTokenService">
        <wsp:PolicyReference URI="#TmaxSTSClientPolicy" />
        ...
    </wsdl:binding>
    <wsdl:service name="SecurityTokenService">
        <wsdl:port name="ISecurityTokenService_Port"
            binding="tns:ISecurityTokenService_Binding">
            <soap:address
                location="http://localhost:8088/trust_sts/STSImplService" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>


다음은 실행 화면이다.

<<__Exception__>>
com.sun.xml.ws.server.UnsupportedMediaException: Unsupported Content-Type:
 application/soap+xml Supported ones are: [text/xml]
  at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:295)
  at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:129)
  at com.sun.xml.ws.encoding.SOAPBindingCodec.decode(SOAPBindingCodec.java:287)
  at jeus.webservices.jaxws.transport.http.HttpAdapter.decodePacket
(HttpAdapter.java:322)
  at jeus.webservices.jaxws.transport.http.HttpAdapter.access$3
(HttpAdapter.java:287)
  at jeus.webservices.jaxws.transport.http.HttpAdapter$HttpToolkit.handle
(HttpAdapter.java:517)
  at jeus.webservices.jaxws.transport.http.HttpAdapter.handle
(HttpAdapter.java:272)
  at jeus.webservices.jaxws.transport.http.EndpointAdapter.handle
(EndpointAdapter.java:149)
  at jeus.webservices.jaxws.transport.http.servlet.WSServletDelegate.doGet
(WSServletDelegate.java:139)
  at jeus.webservices.jaxws.transport.http.servlet.WSServletDelegate.doPost
(WSServletDelegate.java:170)
  at jeus.webservices.jaxws.transport.http.servlet.WSServlet.doPost
(WSServlet.java:23)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:818)
  at jeus.servlet.engine.ServletWrapper.executeServlet(ServletWrapper.java:328)
  at jeus.servlet.engine.ServletWrapper.execute(ServletWrapper.java:222)
  at jeus.servlet.engine.HttpRequestProcessor.run(HttpRequestProcessor.java:278)
<<__!Exception__>>
[2999.01.01 00:00:00][0][bxxx] [TMAX-xx] Unsupported Content-Type:
 application/soap+xml Supported ones are: [text/xml]
<<__Exception__>>
com.sun.xml.ws.server.UnsupportedMediaException: Unsupported Content-Type:
 application/soap+xml Supported ones are: [text/xml]
  at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:295)
  at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:129)
  at com.sun.xml.ws.encoding.SOAPBindingCodec.decode(SOAPBindingCodec.java:287)
  at jeus.webservices.jaxws.transport.http.HttpAdapter.decodePacket
(HttpAdapter.java:322)
  at jeus.webservices.jaxws.transport.http.HttpAdapter.access$3
(HttpAdapter.java:287)
  at jeus.webservices.jaxws.transport.http.HttpAdapter$HttpToolkit.handle
(HttpAdapter.java:517)
  at jeus.webservices.jaxws.transport.http.HttpAdapter.handle(HttpAdapter.java:272)
  at jeus.webservices.jaxws.transport.http.EndpointAdapter.handle
(EndpointAdapter.java:149)
  at jeus.webservices.jaxws.transport.http.servlet.WSServletDelegate.doGet
(WSServletDelegate.java:139)
  at jeus.webservices.jaxws.transport.http.servlet.WSServletDelegate.doPost
(WSServletDelegate.java:170)
  at jeus.webservices.jaxws.transport.http.servlet.WSServlet.doPost
(WSServlet.java:23)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:818)
  at jeus.servlet.engine.ServletWrapper.executeServlet(ServletWrapper.java:328)
  at jeus.servlet.engine.ServletWrapper.execute(ServletWrapper.java:222)
  at jeus.servlet.engine.HttpRequestProcessor.run(HttpRequestProcessor.java:278)
<<__!Exception__>>
user alice is a validate user.
your company : Tmaxsoft
your department : Infra

클라이언트를 실행하면 클라이언트가 STS의 URL 정보를 얻기 위해 여러 가지 접미 URL을 통해 연결을 시도한다. 여기서 로그 레벨이 'FINE' 이상인 경우 위와 같은 Exception이 발생하는 것을 확인할 수 있다.

JEUS 웹 서비스의 메시지 수준 보안은 웹 서비스 보안 정책(Web Service Secure Policy)을 통해 동작한다. 즉, WSDL 문서 내에 직접적으로 웹 서비스 보안 정책을 설정하거나 wsit-endpoint.xml에 웹 서비스 보안 정책을 설정한다.

JEUS에서는 추가적으로 service-config.xml을 통해 웹 서비스 정책 설정을 지원하며 이는 웹 서비스 보안 정책을 지원한다. 따라서 사용자가 웹 서비스 정책 및 웹 서비스 정책에 대해 모르더라도 서버와 클라이언트 간에 이러한 service-config.xml 파일의 공유가 가능하다면 이 파일을 통해 양 끝단의 메시지 수준의 보안을 간단하게 처리할 수 있다. 이는 JAX-RPC(JEUS 5) 웹 서비스의 메시지 수준 보안 방식과 유사하다.

웹 서비스 메시지 수준 보안에서 암호화(Encryption)에 대한 설정은 다음과 같이 구분된다.

  • JAX-RPC 웹 서비스 설정

  • JAX-WS 웹 서비스 설정

JAX-RPC 웹 서비스 설정

JAX-RPC 웹 서비스 메시지 수준 보안에서 암호화를 설정하는 방식은 다음과 같이 jeus-webservices-dd.xml(서버)와 jeus-web-dd.xml(클라이언트)를 설정한다.


JAX-WS 웹 서비스 설정

JAX-WS(JEUS 8.5) 웹 서비스의 메시지 수준 보안은 웹 서비스를 생성(wsgen 또는 wsimport 통해 웹 서비스를 생성)할 때 service-config.xml 파일을 추가적으로 -policy 인자와 함께 명령문에 설정한다.


웹 서비스 메시지 수준 보안에서 서명(Signature)에 대한 설정은 다음과 같이 구분된다.

  • JAX-RPC 웹 서비스 설정

  • JAX-WS 웹 서비스 설정

JAX-RPC 웹 서비스 설정

JAX-RPC 웹 서비스 메시지 수준 보안에서는 다음과 같이 jeus-webservices-dd.xml(서버) 또는 jeus-web-dd.xml(클라이언트)으로 서명을 설정한다.


JAX-WS 웹 서비스 설정

JAX-WS(JEUS 8.5) 웹 서비스의 메시지 수준 보안은 웹 서비스를 생성(wsgen 혹은 wsimport 통해 웹 서비스를 생성)할 때 service-config.xml 파일을 추가적으로 -policy 인자와 함께 명령문에 설정한다.


웹 서비스 메시지 수준 보안에서 Timestamp의 설정은 다음과 같이 구분된다.

  • JAX-RPC 웹 서비스 설정

  • JAX-WS 웹 서비스 설정

JAX-RPC 웹 서비스 설정

JAX-RPC 웹 서비스 메시지 수준 보안에서는 다음과 같이 jeus-webservices-dd.xml(서버) 또는 jeus-web-dd.xml(클라이언트)로 Timestamp를 설정한다.


JAX-WS 웹 서비스 설정

JAX-WS(JEUS 8.5) 웹 서비스의 메시지 수준 보안은 웹 서비스를 생성할 때, 즉 wsgen 또는 wsimport로 웹 서비스를 생성할 때 service-config.xml 파일을 추가적으로 -policy 인자와 함께 명령문에 설정한다.

[예 17.34] JAX-WS(JEUS 8.5) 웹 서비스 Timestamp 설정 : << service-config.xml >>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<web-services-config xmlns="http://www.tmaxsoft.com/xml/ns/jeus">
    <policy>
        <endpoint-policy-subject>
            <portcomponent-wsdl-name>PingPort</portcomponent-wsdl-name>
            <security-policy>
                <security-binding>
                    <asymmetric-binding>
                        <initiator-token>
                            <x509-token/>
                        </initiator-token>
                        <recipient-token>
                            <x509-token/>
                        </recipient-token>
                    </asymmetric-binding>
                    <timestamp>true</timestamp>
                </security-binding>
                <keystore>
                    <keystore-file>
                        <alias>xws-security-client</alias>
                        <key-type>JKS</key-type>
                        <keystore-password>changeit</keystore-password>
                        <keystore-filename>
                            client-keystore.jks
                        </keystore-filename>
                    </keystore-file>
                </keystore>
                <truststore>
                    <keystore-file>
                        <alias>xws-security-server</alias>
                        <key-type>JKS</key-type>
                        <keystore-password>changeit</keystore-password>
                        <keystore-filename>
                            client-truststore.jks
                        </keystore-filename>
                    </keystore-file>
                </truststore>
            </security-policy>
            <operation-policy-subject>
                <operation-wsdl-name>ping</operation-wsdl-name>
                <input-message-policy-subject>
                    <security-policy>
                        <protection>
                            <signed-part>
                                <body/>
                            </signed-part>
                        </protection>
                    </security-policy>
                </input-message-policy-subject>
                <output-message-policy-subject>
                    <security-policy>
                        <protection>
                            <signed-part>
                                <body/>
                            </signed-part>
                        </protection>
                    </security-policy>
                </output-message-policy-subject>
            </operation-policy-subject>
        </endpoint-policy-subject>
    </policy>
</web-services-config>

웹 서비스 메시지 수준 보안에서 사용자명 토큰(Username Token)의 설정은 다음과 같이 구분된다.

  • JAX-RPC 웹 서비스 설정

  • JAX-WS 웹 서비스 설정

JAX-RPC 웹 서비스 설정

JAX-RPC 웹 서비스 메시지 수준 보안에서는 다음과 같이 jeus-webservices-dd.xml(서버) 또는 jeus-web-dd.xml(클라이언트)로 Timestamp를 설정한다.


JAX-WS 웹 서비스 설정

JAX-WS(JEUS 8.5) 웹 서비스의 메시지 수준 보안은 웹 서비스를 생성(wsgen 또는 wsimport 통해 웹 서비스를 생성)할 때 service-config.xml 파일을 추가적으로 -policy 인자와 함께 명령문에 설정한다.


JEUS 웹 서비스는 접근이 허용된 사용자만이 웹 서비스를 호출할 수 있도록 접근 제어 설정을 할 수 있으며, 웹 서비스 Back-end에 따라 각각 설정법이 다르다. JEUS 웹 서비스의 접근 제어 설정 방법은 “27.4. 접근 제어 설정”과 동일하며 클라이언트의 호출 방식만 다르다.

접근 제어(Basic Authentication)가 설정된 웹 서비스의 호출을 하기 위해서는 WSDL에 접근하여 그 내용을 바탕으로 Portable Artifact를 생성하고, 그것을 사용하여 웹 서비스를 호출해야 하는데, 이 경우에 사용자 이름과 암호를 요구할 경우 설정하는 작업이 필요하다.

JAX-WS 웹 서비스 클라이언트가 스스로 인증하기 위해서는 다음과 같은 2가지의 설정이 클라이언트 프로그램 내에 삽입되어야 한다.

다음 예는 실제로 프로그램에서 위 설정을 구현한 예이다.

Echo port = // … SEI(Service Endpoint Interface)의 획득
((javax.xml.ws.BindingProvider) port).getRequestContext().
    put(javax.xml.ws.BindingProvider.USERNAME_PROPERTY, "jeus");
((javax.xml.ws.BindingProvider) port).getRequestContext().
    put(javax.xml.ws.BindingProvider.PASSWORD_PROPERTY, "jeus");
String s = port.echoString("JEUS");

런타임에 JAX-WS 웹 서비스 클라이언트 엔진은 동적 Stub을 생성하기 위해 원격 WSDL에 한 번 접근하는데, 이때 부가적인 권한 설정이 필요하다. 이러한 권한 설정은 java.net.Authenticator 클래스를 사용하여 클라이언트 프로그램에 설치한다.

다음은 java.net.Authenticator 클래스를 사용한 클라이언트 프로그램의 예이다.