WSS API 및 메시지 레벨 보호를 사용하여 외부 STS에서 SAML 전송자 인증 토큰 요청
외부 STS(Security Token Service)에서 전송자 인증 주제 확인 메소드를 포함하는 SAML 토큰을 요청할 수 있습니다. SAML 전송자 인증 토큰을 얻은 후에는 메시지 레벨 보호와 함께 JAX-WS(Java™ API for XML-Based Web Services) 프로그래밍 모델 및 WSS API(Web Services Security API)를 사용하여 이러한 토큰을 웹 서비스 메시지 요청과 함께 전송할 수 있습니다.
시작하기 전에
이 태스크에서는 사용자가 JAX-WS 프로그래밍 모델, WSS API 인터페이스, SAML 개념, SSL 전송 보호, X.509 보안 토큰 및 웹 서비스 설정을 구성하고 관리하기 위한 정책 세트 사용에 익숙한 것으로 가정합니다.
이 태스크 정보
외부 STS에서 전송자 인증 주제 확인 메소드를 포함하는 SAML 토큰을 요청한 다음 메시지 레벨 보호와 함께 WSS API를 사용하여 웹 서비스 클라이언트에서 웹 서비스 요청 메시지로 SAML 토큰을 전송할 수 있습니다.
이 제품은 전송자 인증 주제 확인 메소드를 포함하는 SAML 토큰을 요구하는 기본 정책 세트를 제공하지 않습니다. 전송자 인증 주제 확인을 포함하는 SAML 토큰을 요구하도록 웹 서비스 보안 정책을 작성하는 방법 및 사용자 정의 바인딩 구성을 작성하는 방법에 대해 자세히 알아보려면 SAML 전송자 인증 토큰에 대한 클라이언트 및 제공자 바인딩에 대해 읽어 보십시오. 정책 및 바인딩을 웹 서비스 제공자에 첨부해야 합니다. 이 태스크에서 설명하고 있는 코드 샘플에서는 웹 서비스 제공자 정책이 SAML 토큰 및 메시지 본문 둘 다 X.509 보안 토큰을 사용하여 디지털로 서명되도록 요구하는 것으로 가정합니다.
이 태스크에서 사용되는 웹 서비스 클라이언트 애플리케이션은 다운로드 가능한 JaxWSServicesSamples 샘플 애플리케이션에 포함되어 있는 수정된 버전의 클라이언트 코드입니다. 샘플의 코드 예는 프로시저에 설명되어 있고 완전하고 즉시 사용 가능한 웹 서비스 클라이언트 샘플이 제공됩니다.
프로시저
결과
외부 STS에서 전송자 인증 확인 메소드를 포함하는 SAML 토큰을 요청했습니다. 토큰을 얻은 후에 JAX-WS 프로그래밍 모델 및 WSS API를 사용하는 메시지 레벨 보호를 사용하여 웹 서비스 요청 메시지와 함께 토큰을 전송했습니다.
예
다음 코드 샘플은 외부 STS로부터 SAML 토큰을 요청하는 방법을 보여주고 메시지 레벨 보호와 함께 웹 서비스 요청 메시지로 해당 SAML 토큰을 전송하는 완전하고 즉시 사용 가능한 웹 서비스 클라이언트 애플리케이션입니다. 이 샘플 코드는 이전에 설명한 프로시저 단계를 보여줍니다.
/**
* The following source code is sample code created by IBM Corporation.
* This sample code is provided to you solely for the purpose of assisting you in the
* use of the technology. The code is provided 'AS IS', without warranty or condition of
* any kind. IBM shall not be liable for any damages arising out of your use of the
* sample code, even if IBM has been advised of the possibility of such damages.
*/
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.callbackhandler.SAMLGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
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.SAMLToken;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.websphere.wssecurity.callbackhandler.X509ConsumeCallbackHandler;
import com.ibm.websphere.wssecurity.callbackhandler.X509GenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.WSSException;
import com.ibm.websphere.wssecurity.wssapi.signature.WSSSignPart;
import com.ibm.websphere.wssecurity.wssapi.signature.WSSSignature;
import com.ibm.websphere.wssecurity.wssapi.verification.WSSVerification;
import com.ibm.websphere.wssecurity.wssapi.token.X509Token;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.saml.config.SamlConstants;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertStore;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.X509Certificate;
import java.util.HashSet;
import java.util.Set;
import java.util.HashMap;
import java.util.Map;
import javax.xml.ws.BindingProvider;
public class SampleSamlSVClient {
private String urlHost = "localhost";
private String urlPort = "9080";
private static final String CONTEXT_BASE = "/WSSampleSei/";
private static final String ECHO_CONTEXT12 = CONTEXT_BASE+"EchoService12";
private String message = "HELLO";
private String uriString = "http://" + 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("com.ibm.SSL.ConfigURL", "profile_root/properties/ssl.client.props");
System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas.conf");
//Request the SAML Token from external STS
WSSFactory factory = WSSFactory.getInstance();
String STS_URI = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
String ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(SamlConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(SamlConstants.SAML_APPLIES_TO, ENDPOINT_URL);
cbackMap1.put(SamlConstants.TRUST_CLIENT_WSTRUST_NAMESPACE, "http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(SamlConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
cbackMap1.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML11_VALUE_TYPE);
cbackMap1.put(SamlConstants.CONFIRMATION_METHOD, "sender-vouches");
SAMLGenerateCallbackHandler cbHandler1 = new SAMLGenerateCallbackHandler(cbackMap1);
// Add UNT to trust request
UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, cbHandler1, "system.wss.generate.saml");
System.out.println("SAMLToken id = " + samlToken.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(samlToken);
// Add X.509 Tokens 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(samlToken);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
sig.addSignPart(sigPart);
sig.addSignPart(WSSSignature.BODY);
// Add timestamp
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
sig.addSignPart(WSSSignature.TIMESTAMP);
gencont.add(sig);
WSSConsumingContext concont = factory.newWSSConsumingContext();
// Prepare to consume timestamp in response message
concont.add(WSSConsumingContext.TIMESTAMP);
// Prepare to verify digital signature in response message
X509Certificate x509cert = null;
try {
InputStream is = new FileInputStream("profile_root/etc/ws-security/samples/intca2.cer");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
x509cert = (X509Certificate) cf.generateCertificate(is);
} catch (FileNotFoundException e1) {
throw new WSSException(e1);
} catch (CertificateException e2) {
throw new WSSException(e2);
}
Set<Object> eeCerts = new HashSet<Object>();
eeCerts.add(x509cert);
java.util.List<CertStore> certList = new java.util.ArrayList<CertStore>();
CollectionCertStoreParameters certparam = new CollectionCertStoreParameters(eeCerts);
CertStore cert = null;
try {
cert = CertStore.getInstance("Collection", certparam, "IBMCertPath");
} catch (NoSuchProviderException e1) {
throw new WSSException(e1);
} catch (InvalidAlgorithmParameterException e2) {
throw new WSSException(e2);
} catch (NoSuchAlgorithmException e3) {
throw new WSSException(e3);
}
if (certList != null) {
certList.add(cert);
}
X509ConsumeCallbackHandler callbackHandlerVer = new X509ConsumeCallbackHandler(
"profile_root/etc/ws-security/samples/dsig-receiver.ks",
"JKS",
"server".toCharArray(),
certList,
java.security.Security.getProvider("IBMCertPath"));
WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);
ver.addRequiredVerifyPart(WSSVerification.BODY);
concont.add(ver);
gencont.process(requestContext);
concont.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);
// 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();
}
}
}
SAMLToken id = _6CDDF0DBF91C044D211271166233407
Retrieving document at 'file:profile_root/.../wsdl/'.
>> CLIENT: SEI Echo to http://localhost:9443/WSSampleSei/EchoService12
>> CLIENT: SEI Echo invocation complete.
>> CLIENT: SEI Echo response is: SOAP12==>>HELLO