서비스 제공자 정책을 사용하기 위한 웹 서비스 클라이언트 및 정책 구성
서비스 제공자가 정책을 WSDL(Web Services Description Language)로 공개하는 경우 WebSphere® Application Server 서비스 클라이언트의 정책 구성은 해당 서비스 제공자가 지원하는 정책을 기반으로 동적으로 구성할 수 있습니다.
서비스 제공자는 해당 정책을 WSDL로 된 WS-PolicyAttachment 형식으로 공개해야 하고 클라이언트는 이러한 제공자 정책을 지원할 수 있어야 합니다. 클라이언트는 정책 구성을 전적으로 제공자의 정책에 기반하거나 부분적으로 클라이언트의 정책 세트 구성에 의해 정의된 제한사항이 있는 제공자의 정책을 기반으로 할 수 있습니다.
클라이언트는 제공자의 WSDL을 구하기 위해 HTTP GET 요청 또는 웹 서비스 메타데이터 교환(WS-MetadataExchange) 프로토콜을 사용하여 제공자 정책을 획득합니다. 관리 콘솔 또는 wsadmin 명령을 사용하여 클라이언트가 제공자 정책을 구하는 방법 및 정책을 획득하는 엔드포인트를 구성할 수 있습니다. WS-MetadataExchange 프로토콜을 사용하여 제공자의 정책을 확보하는 경우에는 적합한 시스템 정책 세트를 사용하여 WS-MetadataExchange GetMetadata 요청의 보안을 설정할 수 있다는 장점이 있습니다.
제공자 정책이 다중 파트 WSDL을 사용하는 경우에는 HTTP GET 요청을 사용하여 제공자의 정책을 확보할 수 있지만 WS-MetadataExchange 프로토콜을 사용할 수 없습니다. 다중 파트 WSDL에 대한 자세한 정보는 WSDL에 대한 주제를 참조하십시오.
웹 애플리케이션 클라이언트측 정책은 런타임 구성으로 계산되고 캐싱됩니다. 이 계산된 정책은 효과적인 정책으로 알려져 있고 계산이 수행되는 조작 또는 엔드포인트에 대한 후속 아웃바운드 웹 서비스 요청에 사용됩니다. 클라이언트의 원래 정책 세트 구성은 변경되지 않습니다.
특정 서비스의 경우, 기본적으로 동적 정책 구성이 한 번 발생하고 이 구성이 서비스를 구현하는 모든 엔드포인트에서 동일하다고 가정됩니다. 구성에 동일한 WSDL이 있기 때문입니다. 이 WSDL을 기반으로 하는 정책 계산은 클라이언트 런타임 시에 캐싱되고(지속적이 아님) 각 대상 서비스와 공유됩니다.
클러스터 환경에서 이는 클라이언트가 웹 서비스의 각 엔드포인트 인스턴스마다 제공자 정책을 다시 획득할 필요가 없음을 의미합니다.
WebSphere Application Server 버전 8.0 이상에서는 다양한 WSDL 문서를 사용하여 클라이언트 서비스에 맞는 WSDL을 구성할 수 있도록 서비스 참조를 구성할 수 있습니다. 기본적으로 서비스 참조는 상위 서비스에서 정책 세트 및 WS-Policy 구성을 상속하지만 원하는 경우 정책 세트 및 WS-Policy 구성을 겹쳐쓸 수 있습니다. 자세한 내용은 WS-Policy를 사용하여 표준 형식으로 정책 교환의 내용을 참조하십시오.
각 엔드포인트 구현 시마다 다른 정책 구성이 필요한 경우에는 각 엔드포인트마다 새로운 포트를 작성해야 합니다. 그런 다음 각 엔드포인트마다 다른 정책 구성을 지정할 수 있습니다.
HTTP, SSL 및 JMS 등과 같은 전송 정책은 WS-PolicyAttachment 형식으로는 표현할 수 없으므로 클라이언트는 서비스 제공자의 전송 정책을 획득할 수 없습니다. 클라이언트에 전송 정책이 필요한 경우에는 클라이언트의 정책 세트 구성의 일부로 이러한 정책을 구성해야 합니다.
HTTP GET 요청의 경우 요청이 엔드포인트와 동일한 위치에서 대상 지정되면 요청은 애플리케이션과 동일한 HTTP 및 SSL 전송 정책을 사용합니다. HTTP GET 요청이 다른 엔드포인트에서 대상 지정되면, 다른 HTTP 및 SSL 전송 정책을 지정하기 위해 시스템 정책 세트를 첨부할 수도 있습니다.
WS-MetadataExchange GetMetadata 요청의 경우 지정된 시스템 정책 세트에서 WS-Security 구성이 사용됩니다. HTTP 전송 특성은 애플리케이션으로부터 상속됩니다.
SAML(Security Assertion Markup Language)을 사용하도록 구성된 클라이언트는 동적 정책 구성을 사용할 수 있습니다. 그러나 해당 클라이언트는 일반 바인딩을 사용하도록 구성해야 합니다.
레지스트리의 정책
클라이언트는 HTTP GET 요청을 사용하여 WSRR(WebSphere Service Registry and Repository) 등과 같은 레지스트리에서 웹 서비스 제공자의 정책 구성을 구할 수 있습니다.
서비스 제공자의 정책에 대한 WSDL 및 그에 해당하는 정책과 정책 첨부는 WSRR 등과 같은 레지스트리에 저장됩니다. 해당 정책은 WS-PolicyAttachments 형식으로 해당 정책 구성을 포함해야 합니다. 클라이언트는 해당 제공자 정책을 지원할 수 있어야 합니다.
레지스트리는 WS-Policy 첨부(예: WSRR 버전 6.2 이상)를 포함하는 WSDL를 게시하기 위해 HTTP GET 요청의 사용을 지원해야 합니다.
클라이언트가 서비스 또는 서비스 참조 레벨에서 레지스트리로부터 얻는 제공자 정책을 적용할 수 있지만 애플리케이션 레벨에서는 아닙니다.
클라이언트와 레지스트리 간에 보안 연결이 있는 경우에는 애플리케이션 서버와 레지스트리 서버 간에 신뢰가 구축되는지 확인해야 합니다.
레지스트리에 인증이 필요한 경우에는 또한 레지스트리에 대한 아웃바운드 서비스 요청을 인증하도록 정책을 구성해야 합니다. 기본적으로, HTTP 및 HTTPS 신임 정보가 웹 서비스 엔드포인트 및 레지스트리 둘 다에 사용됩니다. 그러므로 권한 신임 정보의 보안을 설정하고 이러한 신임 정보가 권한 없는 엔드포인트로 전송되지 않도록 하는 것이 좋습니다. 또한 다른 HTTP 및 SSL 전송 정책을 지정하기 위해 시스템 정책 세트를 첨부할 수도 있습니다.
정책 상속
제공자 정책은 애플리케이션 또는 서비스 레벨에서 첨부할 수 있습니다. 엔드포인트 및 조작은 관련 서비스로부터 정책 구성을 상속합니다.
정책 계산
- 제공자 정책만을 지정할 때 계산된 정책은 제공자 정책에 의해 교차된 WebSphere Application Server 클라이언트가 지원하는 모든 정책을 기반으로 합니다. 사실상 클라이언트가 정책을 지원할 수 있는 동안에는 제공자가 정책을 판별합니다. 이 정책 구성은 제공자 정책이 첨부된 범위 지점(엔드포인트 조작)이 클라이언트 정책 세트에 첨부되어 있지 않고 상위 범위 지점으로부터 정책 세트 첨부를 상속받지 않는 경우에 사용 가능합니다.
- 클라이언트 및 제공자 정책을 지정할 때, 계산된 정책은 제공자 정책에 의해 교차된 클라이언트에 수락 가능한 정책을 기반으로 합니다. 사실상 정책이 클라이언트 정책 세트를 준수하지만 제공자가 정한 정책에 의해 추가로 제한될 수도 있습니다. 클라이언트에 수락 가능한 정책은 클라이언트 범위 지점에 첨부되어 있거나 클라이언트 범위 지점이 상위 범위 지점으로부터 상속받은 정책 세트에 의해 정의되어 있습니다. 이 정책 구성은 제공자 정책이 첨부된 범위 지점(엔드포인트 조작)이 클라이언트 정책 세트에 첨부되어 있고 상위 범위 지점으로부터 정책 세트 첨부를 상속받은 경우에 사용 가능합니다.
WS-Policy 언어는 여러 개의 정책 선택사항을 표현하는 방법을 제공하므로 정책 계산은 둘 이상의 결과를 생성할 수도 있습니다. 예를 들어, 서비스 제공자가 WS-ReliableMessaging 1.0 및 WS-ReliableMessaging 1.1 둘 다 지원할 수도 있습니다. 클라이언트가 또한 두 버전을 모두 지원하는 경우에는 클라이언트는 제공자에 대한 웹 서비스 요청에 두 버전을 모두 사용할 수 있습니다. 이 상황에서는 클라이언트와 제공자 둘 다에 둘 이상의 스펙 버전이 수락 가능하므로 가장 최신 버전을 사용하여 계산하는 것이 효과적인 정책입니다.
JAX-WS 디스패치 클라이언트에서 정책 교차점
- 클라이언트는 제공자 정책이 서비스가 제공하는 모든 조작과 동일한 경우에만(의미론적 및 구문론적 모두) 조작으로 범위 지정된 제공자 정책을 준수합니다.
- 제공자 정책이 서비스가 제공하는 모든 조작과 동일하지 않은 경우에는 클라이언트는 WSPolicyException(CWPOL0106E) 원인 및 적합한 오류 메시지와 함께 JAX-WS WebserviceException을 리턴합니다.
- 조작에 정책이 없는 경우 클라이언트는 서비스 엔드포인트에 효과적인 제공자 정책을 사용합니다.
클라이언트가 보유한 제공자 정책 새로 고치기
클라이언트가 서비스에 대해 보유하는 제공자 정책은 애플리케이션이 시작된 후 처음으로 웹 서비스가 호출될 때 새로 고쳐집니다. 그 이후 제공자 정책은 애플리케이션이 다시 시작하거나 제공자 정책의 업데이트를 명시적으로 호출하는 경우에 새로 고쳐집니다. 제공자 정책이 새로 고쳐지면 유효 정책은 다시 계산됩니다.
애플리케이션 코드에서 제공자 정책의 업데이트를 호출할 수 있습니다. 이는 JAX-WS 호출이 실패한 경우에 유용합니다. 예외 처리 시에 새로 고쳐진 정책으로 재시도를 강제 실행할 수 있습니다. JAX-WS 클라이언트 프록시에 com.ibm.websphere.wspolicy.refreshProviderPolicy 특성(API의 WSPConstants 클래스에서 사용 가능)을 설정한 다음 JAX-WS 요청을 재발행할 수 있습니다.
com.ibm.websphere.wspolicy.refreshProviderPolicy 특성이 설정되면 클라이언트가 서비스에 대해 보유하고 있는 제공자 정책이 새로 고쳐지고 다음 요청 시에 효과적인 정책이 재계산됩니다. 새로 고침 및 재계산이 발생한 후에는 com.ibm.websphere.wspolicy.refreshProviderPolicy 특성이 설정 해제됩니다.
디스패치 클라이언트의 다음 코드 예제는 제공자 정책을 새로 고친 후 새로 고치기를 호출하여 해결할 수 있는 예외 식별을 보여줍니다.
try
{
dispatch.invoke(params);
}
catch (javax.xml.ws.WebServiceException e)
{
Throwable cause = e.getCause();
if ((cause instanceof NullPolicyException) || (cause instanceof PolicyException) )
{
// The exception might be because the policy of the provider is not up to date.
//
// There is also a message on the console that starts with the characters CWPOL,
// which helps to decipher and debug the cause of the error.
// This message is also available by using
// String nlsedMessage = cause.getMessage();
Map<String, Object> requestContext = dispatch.getRequestContext();
requestContext.put(WSPConstants.REFRESH_PROVIDER_POLICY, Boolean.TRUE);
// The following method might cause another jax-ws invocation exception.
// The cause might still be policy, in which case, a message is written to the
// console.
dispatch.invoke(params);
}
// For all other exceptions, use the normal exception handling for the
// application. In this case, assume there are no other exceptions and rethrow the
// initial exception. Remember that the WebServiceException might be caused by a
// WSPolicyAdministrationException. In this situation, a message is written to the
// console, but forcing a refresh in the application cannot resolve the problem.
throw e;
}