외부 STS(Security
Token Service)로부터 인증 토큰을 요청한 다음 메시지 또는 전송 레벨 보호와 함께 JAX-WS(Java™ API
for XML-Based Web Service) 프로그래밍 모델 및 WSS API(Web Services
Security API)를 사용하여 웹 서비스 요청 메시지와 해당 토큰을 전송할 수 있습니다.
시작하기 전에
이 태스크에서는 사용자가 JAX-WS
프로그래밍 모델, WSS API 인터페이스, WebSphere® 웹 서비스 보안 일반 보안 토큰 로그인 모듈, SSL 전송 보호, 메시지 레벨 보호 및 웹 서비스 설정을 구성하고 관리하기 위한 정책 세트 사용에 익숙한 것으로 가정합니다.
이 태스크 정보
이 태스크에서 사용되는
웹 서비스 클라이언트 애플리케이션은 다운로드 가능한 JaxWSServicesSamples 샘플
애플리케이션에 포함되어 있는 수정된 버전의 클라이언트 코드입니다. 샘플의 코드 스니펫은
프로시저에 설명되어 있고 완전하고 즉시 사용 가능한 웹 서비스 클라이언트 샘플이 제공됩니다.
외부 STS로부터 SAML 전달자 인증 토큰을 요청한 후 전송하려면 다음 단계를 완료하십시오.
프로시저
- 웹 서비스 제공자를 호출하는 데 사용할 웹 서비스 클라이언트를 식별하고 얻으십시오. WSS API를 사용하여 SOAP 요청 메시지에 있는 인증 토큰을 프로그래밍 방식으로 요청하고 삽입하려면
이 클라이언트를 사용하십시오. 이 프로시저에서 사용되는 웹 서비스 클라이언트는
JaxWSServicesSamples 웹 서비스 샘플 애플리케이션에 포함되어 있는 수정된 버전의 클라이언트 코드입니다.
WSS API를 사용하여 SOAP 요청 메시지에 있는 보안 토큰을 프로그래밍 방식으로 전달하기 위해
웹 서비스 보안 API를 추가할 샘플 웹 서비스 클라이언트를 얻고 수정하려면 다음 단계를 완료하십시오.
- JaxWSServicesSamples 샘플 애플리케이션을 다운로드하십시오. JaxWSServicesSamples 샘플은 기본적으로 설치되지 않습니다.
- JaxWSServicesSamples 클라이언트 코드를 얻으십시오. 이 예를 위해 이 프로시저는 JaxWSServicesSamples 샘플에 포함되어 있는
수정된 버전의 Echo 씬 클라이언트 샘플을 사용합니다. 웹 서비스 Echo 씬 클라이언트 샘플 파일인 SampleClient.java는
src\SampleClientSei\src\com\ibm\was\wssample\sei\cli 디렉토리에 있습니다.
샘플 클래스 파일은 WSSampleClientSei.jar 파일에 포함되어 있습니다.
JaxWSServicesSamples.ear 엔터프라이즈 애플리케이션 및
지원하는 JAR(Java Archives) 파일은 JaxWSServicesSamples 샘플
애플리케이션내 installableApps 디렉토리에 있습니다.
- JaxWSServicesSamples.ear 파일을 애플리케이션 서버에 배치하십시오. JaxWSServicesSamples.ear 파일 배치를 완료했으면
샘플 웹 서비스 클라이언트 코드를 샘플 애플리케이션에 대해 테스트할 준비가 된 것입니다.
웹 서비스 클라이언트 샘플의 보호를 위해 PolicySet를 사용하는 대신
자신의 고유 웹 서비스 클라이언트 애플리케이션에서 WSS API를 사용하여 SOAP 요청 메시지에 있는 인증 토큰을 프로그래밍 방식으로 전달하기 위해 코드 스니펫을 추가하도록 선택할 수 있습니다. 이 프로시저의 예에서는 JAX-WS 웹 서비스 씬 클라이언트를 사용하지만 관리 클라이언트를 사용할 수도 있습니다.
- SAML11 Bearer WSHTTPS 기본 정책 세트를 웹 서비스 제공자에 첨부하십시오. 이 정책 세트는 HTTPS 전송을 사용하여 메시지를 보호하는 데 사용됩니다. SAML11 Bearer WSHTTPS 기본 정책 세트를
웹 서비스 제공자에 첨부하는 방법에 대한 세부사항은 SAML 전달자 토큰에 대한 클라이언트 및 제공자 바인딩에 대해 읽어 보십시오.
- SAML 전달자 제공자 샘플 기본 일반 바인딩을 샘플 웹 서비스 제공자에 지정하십시오. SAML 전달자 제공자 샘플 기본 일반 바인딩을 웹 서비스 애플리케이션에 지정하는 것에 대한 세부사항은
SAML 전달자 토큰에 대한 클라이언트 및 제공자 바인딩 구성에 대해 읽어 보십시오.
- trustStoreType, trustStorePassword 및
trustStorePath 사용자 정의 특성이 STS 서명자 인증서를 포함하는 신뢰 저장소에 해당되는지 검증하십시오. 관리 콘솔을 사용하여 다음 단계를 완료하십시오.
- 를 클릭하십시오.
- 인증 토큰 테이블에서 con_saml11token을 클릭하십시오.
- 콜백 핸들러를 클릭하십시오.
- 사용자 정의 특성 섹션에서 trustStoreType, trustStorePassword 및
trustStorePath 사용자 정의 특성이 STS 서명자 인증서를 포함하는 신뢰 저장소에 해당되는지 확인하십시오.
- 웹 서비스 요청 또는 WS-Trust 요청을 보호하기 위해 SSL 전송 레벨 보호를 사용하는 경우
다음 JVM(Java Virtual Machine) 특성을 사용하여 SSL 구성을 설정하십시오.
-Dcom.ibm.SSL.ConfigURL=file:<profile_root>\properties\ssl.client.props
또는 샘플 클라이언트 코드에서 Java 시스템 특성을 사용하여 SSL 구성 파일을 정의할 수 있습니다.
System.setProperty("com.ibm.SSL.ConfigURL", "file:profile_root/properties/ssl.client.props");
- JAX-WS 씬 클라이언트의 JAR 파일을 다음 클래스 경로에 추가하십시오. app_server_root/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar. 이 JAR 파일을 클래스 경로에 추가하는 것에 대한 자세한 정보는
웹 서비스 사용 클라이언트 테스트 정보를 참조하십시오.
- 외부 STS에서 인증 토큰을 요청하십시오. 다음 코드 스니펫은 WebSphere 일반 SecurityToken 로그인 모듈에서 사용할 인증 토큰을 요청하는 방법을 보여주고 외부 STS가 인증 토큰으로 Username 토큰을 승인하고 SAML 1.1 토큰을 발행하도록 구성되는 것으로 가정합니다.
//Request SecurityToken from external STS:
WSSFactory factory = WSSFactory.getInstance();
//STS URL that issues the requested token
String STS_URI = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
//Web services endpoint that receives the issued token
String ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
//Begin sample code 1 (Using WS-Trust Issue to request the token from
//the STS in which authentication token is send over WS-Security head):
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//The following property specifies that the ws-trust request should be
//compliance with WS-Trust 1.3 spec
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
//This request is made with WS-TRust Issue only (without the use of
//WS-Trust Validate)
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT, "false");
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Create the context object for WS-Trust request:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT for trust request authentication
UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//End of sample code 1.
//Begin sample code 2 (using WS-Trust Validate to request a token by
//exchanging a token in RunAs Subject).
//If web service client has RunAs Subject , for example an
//authenticated intermediate server acts as a client to invoke the
//downstream service, you can program the client to use the token from
//the RunAs subject to exchange with the STS by using WS-Trust validate.
//To do so, you replace sample code 1 with the following:
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//This request is made with WS-Trust 1.3
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
//add the next line if you do not want to fallback to WS-Trust Issue if
//token exchange fails.
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY, "true");
//add the next line to specify the token type in the RunAs subject that
//will be used to exchange the requested token. For example, you use
//the LTPA token to exchange for a SAML token. If the exchanged token
//in the RunAs subject has the same value type as the requested token,
//setting IssuedTokenConfigConstants.USE_TOKEN is not required.
cbackMap1.put(IssuedTokenConfigConstants.USE_TOKEN, LTPAToken.ValueType);
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//The following codes are added if Authentication token in ws-security
//head or Message level security protection is required. If there is no
//Message level protection or additional authentication token for
//WS-Trust Validate, do not create the context object shown below.
//Context object for WS-Trust request:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT for trust request authentication
UNTGenerateCallbackHandler utCallbackHandler =
new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//End of sample code 2.
GenericSecurityToken token = (GenericSecurityToken) factory.newSecurityToken
(GenericSecurityToken.class, cbHandler1, "system.wss.generate.issuedToken");
//The following step to set the ValueType is required..
//The parameter is always the QName of the requested token's valueType.
//QName for SAML1.1:
QName Saml11ValueType = new QName(WSSConstants.SAML.SAML11_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//Includes QName definitions for SAML11, SAML20, TAM
//token, and Pass ticket token.
//QName for SAML 2.0:
QName Saml20ValueType = new QName(WSSConstants.SAML.SAML20_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//QName for TAM token:
QName TamValueType = new QName("http://ibm.com/2004/01/itfim/ivcred");
//QName for PassTicket token:
QName PassTicketValueType = new QName("http://docs.oasis-open.org/wss/
2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken");
//You can use the Token interface to get the token ValueType QName for
//all other tokens. For example, a Username Token's QName is //UsernameToken.ValueType.
GenericIssuedTokenGenerateCallbackHandler 오브젝트는
요청하는 보안 토큰의 특성을 정의하는 매개변수와 STS에 연결하여 보안 토큰을 얻기 위해
필요한 기타 매개변수를 포함합니다. GenericIssuedTokenGenerateCallbackHandler 오브젝트는
다음 테이블에 설명되어 있는 구성 매개변수를 지정합니다.
표 1. GenericIssuedTokenGenerateCallbackHandler 특성. 이 테이블은 GenericIssuedTokenGenerateCallbackHandler 오브젝트에 대한 구성 매개변수를 설명하고
이 특성이 필요한지 여부를 지정합니다. 특성 |
설명 |
Required |
IssuedTokenConfigConstants.STS_ADDRESS |
STS의 http 주소를 지정합니다. STS에 대한 통신이 SSL로 보호되는 경우 -Dcom.ibm.SSL.ConfigURL 특성을 설정해야 합니다.
STS에 대한 SSL 연결은 https:// 주소 접두부로 표시됩니다.
|
예 |
IssuedTokenConfigConstants.APPLIES_TO |
토큰을 사용하려는 대상 서비스 주소를 지정합니다. |
아니오 |
IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST |
STS에서 RequestSecurityToken (RST) 요소로 묶인 단일 토큰을 요청할지 또는 단일 RequestSecurityTokenCollection (RSTC) 요소로 묶인 RST 요소 콜렉션에 있는 여러 토큰을 요청할지 여부를 지정합니다.
기본 동작은 STS에서 RequestSecurityToken (RST) 요소로 묶인 단일 토큰을 요청하는 것입니다.
이 특성에
true 값을 지정하는 것은 STS에서 단일 RequestSecurityTokenCollection (RSTC) 요소로 묶인 RST 요소의 콜렉션에 있는 여러 토큰을 요청하는 것을 나타냅니다.
기본값은 false입니다.
|
아니오 |
IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE |
WS-Trust 요청에 포함된 WS-Trust 네임스페이스를 지정합니다. 기본값은 WSTrust 1.3입니다.
|
아니오 |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT |
WS-Trust Validate를 사용하여 요청된 토큰을 먼저 교환하기 위해 WS-Security가 RunAs 주제의 토큰을 사용하도록 하려는 경우 지정하십시오. false로 설정되면 WS-Security가 WS-Trust Issue를 사용하여
토큰을 요청합니다. 기본값은 true입니다.
|
아니오 |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY |
토큰 교환에 실패한 경우 WS-Security가 요청한 토큰에 대해 WS-Trust Issue를 사용하지 않도록 하려는 경우에 지정하십시오. 기본값은 false입니다.
|
아니오 |
IssuedTokenConfigConstants.USE_TOKEN |
요청된 토큰을 교환하기 위해 RunAs
주제에서 토큰을 선택하려면 이 값을 사용하십시오. 기본값은 요청된 토큰의 ValueType입니다.
|
아니오 |
WSSGenerationContext 인스턴스 및 WSSConsumingContext 인스턴스도
GenericIssuedTokenGenerateCallbackHandler 오브젝트에서 설정됩니다.
이 예에서 WSSGenerationContext 인스턴스는
STS에 전송할 UsernameToken을 작성하기 위한 정보가 들어 있는 UNTGenerateCallbackHandler 오브젝트를 포함합니다.
system.wss.generate.issuedToken 매개변수는
일반 보안 토큰을 작성하기 위해 사용되는 JAAS(Java Authentication
and Authorization Service) 로그인 모듈을 지정합니다. 필수 JAAS 로그인 구성을 포함하는 JAAS 구성 파일을 정의하도록 JVM 특성을 지정해야 합니다. 예를 들면, 다음과 같습니다.
-Djava.security.auth.login.config=profile_root/properties/wsjaas_client.conf
또는 샘플 클라이언트 코드에서 Java 시스템 특성을 설정하여
JAAS 로그인 구성 파일을 지정할 수 있습니다. 예를 들면, 다음과 같습니다.
System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf");
- STS의 요청된 인증 토큰을 웹 서비스 요청 메시지의 SOAP 보안 헤더에 추가하십시오.
- 웹 서비스 클라이언트를 초기화하고 SOAPAction 특성을 구성하십시오. 다음 코드는 이러한 조치를 보여줍니다.
// Initialize web service client
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// Configure SOAPAction properties
BindingProvider bp = (BindingProvider) (echo._getDescriptor().getProxy());
Map<String, Object> requestContext = bp.getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);
requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoOperation");
// Initialize WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
- WSSGenerationContext 오브젝트를 초기화하십시오. 다음 코드는 WSSGenerationContext 오브젝트를 얻기 위해 WSSFactory.newWSSGenerationContext 메소드를
사용하는 것을 보여줍니다. 그러면 WSSGenerationContext 오브젝트가
토큰을 웹 서비스 요청 메시지에 삽입하는 데 사용됩니다.
// Initialize WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
WSSGenerationContext.add 메소드에서
클라이언트 코드에는 다음 Java 2 Security 권한이 있어야 합니다.
permission javax.security.auth.AuthPermission "modifyPrivateCredentials"
- 메시지 보호를 위해 X.509 토큰을 추가하십시오(웹 서비스가 SSL 전송 레벨 보호만으로 보호되는 경우에는 이 단계를 건너뜀). 다음 샘플 코드에서는 dsig-sender.ks 키 파일 및 SOAPRequester 샘플 키를 사용합니다. 프로덕션 환경에서는 이 샘플 키를 사용해서는 안됩니다. 다음 코드는 메시지 보호를 위해 X.509 토큰을 추가하는 것을 보여줍니다.
//Add an X.509 Token for message protection
X509GenerateCallbackHandler x509callbackHandler = new X509GenerateCallbackHandler(
null,
"profile_root/etc/ws-security/samples/dsig-sender.ks",
"JKS",
"client".toCharArray(),
"soaprequester",
"client".toCharArray(),
"CN=SOAPRequester, OU=TRL, O=IBM, ST=Kanagawa, C=JP", null);
SecurityToken x509 = factory.newSecurityToken(X509Token.class,
x509callbackHandler, "system.wss.generate.x509");
WSSSignature sig = factory.newWSSSignature(x509);
sig.setSignatureMethod(WSSSignature.RSA_SHA1);
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
sig.addSignPart(sigPart);
sig.addSignPart(WSSSignature.BODY);
- X.509 토큰을 포함하는 WSSSignature 오브젝트를 작성하십시오. 다음 코드 행은 X.509 토큰을 포함하는 WSSSignature 오브젝트를 작성합니다.
WSSSignature sig = factory.newWSSSignature(x509);
- 메시지 보호를 위해 사용할 서명된 파트를 추가하십시오. 다음 코드 행은 서명된 파트로 WSSSignature.BODY를 추가하도록 지정합니다.
sig.addSignPart(WSSSignature.BODY);
- SOAP 보안 헤더에서 Timestamp 요소를 추가하십시오. SAML20 SenderVouches WSHTTPS 및 SAML11
SenderVouches WSHTTPS 정책 세트에서는 웹 서비스 요청 및 응답이
그 SOAP 보안 헤더에 Timestamp 요소를 포함하도록 요구합니다. 다음 코드에서
WSSFactory.newWSSTimestamp() 메소드는 Timestamp 요소를 생성하고 WSSGenerationContext.add(timestamp) 메소드는 Timestamp 요소를 요청 메시지에 추가합니다.
// Add Timestamp element
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
sig.addSignPart(WSSSignature.TIMESTAMP);
gencont.add(sig);
WSSConsumingContext concont = factory.newWSSConsumingContext();
- 토큰 서명이 요구되지 않으면 이 단계를 건너뛰십시오. 요청된 보안 토큰이 STR
Dereference Transform 참조 옵션을 사용하여 서명되어야 하는 경우 1단계를 따르십시오. 그렇지 않은 경우에는
2단계를 따르십시오. STR Dereference Transform 참조 옵션은 일반적으로 STR-Transform이라고 합니다.
1단계: SAML 토큰을 포함한 일부 토큰은 디지털로 직접 서명할 수 없습니다. STR-Transform을 사용하여 토큰에 서명해야 합니다.
STR-Transform을 사용하여 토큰이 서명되도록 하려면
<wsse:Security> 헤더 블록의 <wsse:SecurityTokenReference>
요소에 의해 이 토큰이 참조되어야 합니다. STR-Transform을 사용하여 보안 토큰에 서명하기 위해
WSSSignPart.TRANSFORM_STRT10 속성으로 표시되는 변환 알고리즘을 통해 SecurityTokenReference를 지정하기 위한 별도의 WSSSignPart가 작성됩니다.
이 속성을 사용하면 WS-Security 런타임 환경이 토큰을 참조하기 위한 SecurityTokenReference 요소를 생성하고
STR Dereference 참조 옵션을 사용하여 토큰에 디지털로 서명할 수 있습니다. 다음 코드는 WSSSignPart.TRANSFORM_STRT10 속성의 사용을 보여줍니다.
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
2단계: 요청된 서명 토큰이 SAML 토큰이 아니거나 STR-Transform을 사용하지 않는 경우 다음 코드를 대신 사용하십시오.
sig.addSignPart(token);
- WSSGenerationContext 오브젝트를 웹 서비스 RequestContext 오브젝트에 첨부하십시오. WSSGenerationContext 오브젝트에는 이제 요청 메시지를 형식화하는 데 필요한
모든 보안 정보가 들어 있습니다. WSSGenerationContext.process(requestContext) 메소드는 WSSGenerationContext 오브젝트를 웹 서비스
RequestContext 오브젝트에 첨부하여 WS-Security 런타임 환경이
필요한 SOAP 보안 헤더를 형식화할 수 있도록 합니다. 예를 들면, 다음과 같습니다.
// Attaches the WSSGenerationContext object to the web service RequestContext object.
gencont.process(requestContext);
- 제공자 정책에서 응답 메시지의 디지털 서명을 요구하는 경우 X.509 토큰을 사용하여 디지털 서명 및 응답 메시지의 무결성을 유효성 검증하십시오. SSL 전송 레벨 보호를 사용하는 경우 이 단계를 건너뛰십시오.
- X509ConsumeCallbackHandler 오브젝트는 신뢰 저장소 및
응답 메시지의 디지털 서명을 유효성 검증하기 위한 인증서 경로 오브젝트 List를 사용하여 초기화됩니다. 다음 코드는 X509ConsumeCallbackHandler 오브젝트를
dsig-receiver.ks 신뢰 저장소 및 certList라고 하는 인증서 경로 오브젝트를 사용하여 초기화합니다.
ArrayList certList = new ArrayList();
java.security.cert.CertStore certStore = java.security.cert.CertStore.getDefaultType();
certList.add(certStore);
X509ConsumeCallbackHandler callbackHandlerVer = new
X509ConsumeCallbackHandler("profile_root/etc/ws-security/samples/dsig-receiver.ks",
"JKS",
"server".toCharArray(),
certList,
java.security.Security.getProvider("IBMCertPath"));
- WSSVerification 오브젝트가 작성되고 WS-Security 런타임 환경이 디지털 서명을 유효성 검증할 수 있도록 메시지 본문이
검증 오브젝트에 추가됩니다. 다음 코드는 WSSVerification 오브젝트를 초기화하는 데 사용됩니다.
WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);
WSSConsumingContext 오브젝트에는 이제 요청 메시지를 형식화하는 데 필요한
모든 보안 정보가 들어 있습니다. WSSConsumingContext.process(requestContext) 메소드는
WSSConsumingContext 오브젝트를 응답 메소드에 첨부합니다. 예를 들면, 다음과 같습니다.
// Attaches the WSSConsumingContext object to the web service RequestContext object.
concont.process(requestContext);
결과
외부 STS에서 보안 토큰을 요청했습니다.
토큰을 얻은 후에
JAX-WS 프로그래밍 모델 및 WSS API를 사용하는 메시지 레벨 보호를 사용하여 웹 서비스 요청 메시지와 함께 토큰을 전송했습니다.
예
다음 코드 샘플은 외부 STS로부터 SAML 전달자 토큰을 요청하고
해당 SAML 토큰을 웹 서비스 요청 메시지로 전송하는 방법을 보여주는 웹 서비스 클라이언트 애플리케이션입니다. 사용 시나리오에서 SAML 토큰을 필요로 하지만 애플리케이션이 웹 서비스 메시지를 사용하여 SAML 토큰을 전달하지 않아도 되는 경우 다음 샘플 코드의 첫 번째 파트인
//
Initialize web service client 섹션까지만 사용하면 됩니다.
package com.ibm.was.wssample.sei.cli;
import com.ibm.was.wssample.sei.echo.EchoService12PortProxy;
import com.ibm.was.wssample.sei.echo.EchoStringInput;
import com.ibm.websphere.wssecurity.wssapi.WSSConsumingContext;
import com.ibm.websphere.wssecurity.wssapi.WSSFactory;
import com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext;
import com.ibm.websphere.wssecurity.wssapi.WSSTimestamp;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
import com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.core.config.IssuedTokenConfigConstants;
import com.ibm.websphere.wssecurity.callbackhandler.GenericIssuedTokenGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityToken;
import javax.xml.namespace.QName;
import java.util.HashMap;
import java.util.Map;
import javax.xml.ws.BindingProvider;
public class SampleSamlSVClient {
private String urlHost = "yourhost";
private String urlPort = "9444";
private static final String CONTEXT_BASE = "/WSSampleSei/";
private static final String ECHO_CONTEXT12 = CONTEXT_BASE+"EchoService12";
private String message = "HELLO";
private String uriString = "https://" + urlHost + ":" + urlPort;
private String endpointURL = uriString + ECHO_CONTEXT12;
private String input = message;
/**
* main()
*
* see printusage() for command-line arguments
*
* @param args
*/
public static void main(String[] args) {
SampleSamlSVClient sample = new SampleSamlSVClient();
sample.CallService();
}
/**
* CallService Parms were already read. Now call the service proxy classes
*
*/
void CallService() {
String response = "ERROR!:";
try {
System.setProperty("java.security.auth.login.config",
"file:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/wsjaas_client.conf ");
System.setProperty("com.ibm.SSL.ConfigURL",
"file:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/ssl.client.props");
//Request the SAML Token from external STS
WSSFactory factory = WSSFactory.getInstance();
String STS_URI = "https://yourhost:9443/TrustServerWST13/services/RequestSecurityToken";
String ENDPOINT_URL = "http://localhost:9081/WSSampleSei/EchoService12";
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT, "false");
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Context object for WS-Trust request:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT for trust request authentication
UNTGenerateCallbackHandler utCallbackHandler = new
UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//get generic security token
GenericSecurityToken token = (GenericSecurityToken) factory.newSecurityToken
(GenericSecurityToken.class, cbHandler1, "system.wss.generate.issuedToken");
QName Saml11ValueType = new QName(WSSConstants.SAML.SAML11_VALUE_TYPE);
token.setValueType(Saml11ValueType);
System.out.println("SAMLToken id = " + token.getId());
// Initialize web services client
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// Configure SOAPAction properties
BindingProvider bp = (BindingProvider) (echo._getDescriptor().getProxy());
Map<String, Object> requestContext = bp.getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);
requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoOperation");
// Initialize WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
// Add timestamp
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
gencont.process(requestContext);
// Build the input object
EchoStringInput echoParm =
new com.ibm.was.wssample.sei.echo.ObjectFactory().createEchoStringInput();
echoParm.setEchoInput(input);
System.out.println(">> CLIENT: SEI Echo to " + endpointURL);
// Prepare to consume timestamp in response message.
WSSConsumingContext concont = factory.newWSSConsumingContext();
concont.add(WSSConsumingContext.TIMESTAMP);
concont.process(requestContext);
// Call the service
response = echo.echoOperation(echoParm).getEchoResponse();
System.out.println(">> CLIENT: SEI Echo invocation complete.");
System.out.println(">> CLIENT: SEI Echo response is: " + response);
} catch (Exception e) {
System.out.println(">> CLIENT: ERROR: SEI Echo EXCEPTION.");
e.printStackTrace();
}
}
}