You can request SAML tokens with the sender-vouches subject confirmation method from an external Security Token Service (STS). After obtaining the SAML sender-vouches token, you can then send these tokens with web services request messages using the Java API for XML-Based Web Services (JAX-WS) programming model and Web Services Security APIs (WSS API) with message level protection.
This task assumes that you are familiar with the JAX-WS programming model, the WSS API interfaces, SAML concepts, SSL transport protection, X.509 security token, and the use of policy sets to configure and administer web services settings.
You can request a SAML token with the sender-vouches subject confirmation method from an external STS and then send the SAML token in web services request messages from a web services client using WSS APIs with message level protection.
newfeatThis product does not provide a default policy set that requires SAML tokens with sender-vouches subject confirmation method. Read about configuring client and provider bindings for the SAML sender-vouches token to learn more about how to create a Web Services Security policy to require SAML tokens with sender-vouches subject confirmation and how to create a custom binding configuration. You must attach the policy and binding to the web services provider. The code sample described in this task assumes that the web services provider policy requires that both the SAML tokens and the message bodies are digitally signed by using an X.509 security token.
The web services client application used in this task is a modified version of the client code that is contained in the JaxWSServicesSamples sample application that is available for download. Code examples from the sample are described in the procedure, and a complete, ready-to-use web services client sample is provided.
You have requested a SAML token with the sender-vouches confirmation method from an external STS. After obtaining the token, you sent the token with web services request messages using message level protection using the JAX-WS programming model and WSS APIs.
The following code sample is a complete, ready-to-use web services client application that demonstrates how to request a SAML token from an external STS and send that SAML token in web services request messages with message level protection. This sample code illustrates the procedure steps described previously.
/** * 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
In this information ...Related tasks
| IBM Redbooks, demos, education, and more(Index) |