1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.ws.security.saml;
21
22 import org.apache.ws.security.WSConstants;
23 import org.apache.ws.security.WSDataRef;
24 import org.apache.ws.security.WSEncryptionPart;
25 import org.apache.ws.security.WSSConfig;
26 import org.apache.ws.security.WSSecurityEngine;
27 import org.apache.ws.security.WSSecurityEngineResult;
28 import org.apache.ws.security.WSSecurityException;
29 import org.apache.ws.security.common.KeystoreCallbackHandler;
30 import org.apache.ws.security.common.SAML1CallbackHandler;
31 import org.apache.ws.security.common.SOAPUtil;
32 import org.apache.ws.security.components.crypto.Crypto;
33 import org.apache.ws.security.components.crypto.CryptoFactory;
34 import org.apache.ws.security.components.crypto.CryptoType;
35 import org.apache.ws.security.message.WSSecDKSign;
36 import org.apache.ws.security.message.WSSecHeader;
37 import org.apache.ws.security.message.token.SecurityTokenReference;
38 import org.apache.ws.security.saml.ext.AssertionWrapper;
39 import org.apache.ws.security.saml.ext.SAMLParms;
40 import org.apache.ws.security.saml.ext.builder.SAML1Constants;
41 import org.apache.ws.security.util.WSSecurityUtil;
42
43 import org.w3c.dom.Document;
44
45 import java.security.cert.X509Certificate;
46 import java.util.ArrayList;
47 import java.util.List;
48
49 import javax.security.auth.callback.CallbackHandler;
50
51
52
53
54
55 public class SamlTokenDerivedTest extends org.junit.Assert {
56 private static final org.apache.commons.logging.Log LOG =
57 org.apache.commons.logging.LogFactory.getLog(SamlTokenDerivedTest.class);
58 private WSSecurityEngine secEngine = new WSSecurityEngine();
59 private CallbackHandler callbackHandler = new KeystoreCallbackHandler();
60 private Crypto crypto = null;
61
62 public SamlTokenDerivedTest() throws Exception {
63 WSSConfig.init();
64 crypto = CryptoFactory.getInstance("crypto.properties");
65 }
66
67
68
69
70
71 @org.junit.Test
72 @SuppressWarnings("unchecked")
73 public void testSAML1AuthnAssertionDerived() throws Exception {
74
75
76
77 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
78 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
79 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
80 callbackHandler.setIssuer("www.example.com");
81
82 SAMLParms samlParms = new SAMLParms();
83 samlParms.setCallbackHandler(callbackHandler);
84 AssertionWrapper assertion = new AssertionWrapper(samlParms);
85
86 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
87 WSSecHeader secHeader = new WSSecHeader();
88 secHeader.insertSecurityHeader(doc);
89
90 SecurityTokenReference secRefSaml =
91 createSamlSTR(doc, assertion, WSSConfig.getNewInstance());
92 secHeader.getSecurityHeader().appendChild(assertion.toDOM(doc));
93 secHeader.getSecurityHeader().appendChild(secRefSaml.getElement());
94
95
96
97
98 WSSecDKSign sigBuilder = createDKSign(doc, secRefSaml);
99 Document signedDoc = sigBuilder.build(doc, secHeader);
100
101 if (LOG.isDebugEnabled()) {
102 LOG.debug("SAML 1.1 Authn Assertion Derived (sender vouches):");
103 String outputString =
104 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
105 LOG.debug(outputString);
106 }
107
108
109 List<WSSecurityEngineResult> results = verify(signedDoc);
110 WSSecurityEngineResult actionResult =
111 WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
112 AssertionWrapper receivedAssertion =
113 (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
114 assertTrue(receivedAssertion != null);
115
116
117 actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
118 assertTrue(actionResult != null);
119 assertFalse(actionResult.isEmpty());
120 final List<WSDataRef> refs =
121 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
122 assertTrue(refs.size() == 2);
123
124 WSDataRef wsDataRef = (WSDataRef)refs.get(0);
125 String xpath = wsDataRef.getXpath();
126 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
127
128 wsDataRef = (WSDataRef)refs.get(1);
129 xpath = wsDataRef.getXpath();
130 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml1:Assertion", xpath);
131 }
132
133
134
135
136 private SecurityTokenReference createSamlSTR(
137 Document doc,
138 AssertionWrapper assertion,
139 WSSConfig wssConfig
140 ) {
141 SecurityTokenReference secRefSaml = new SecurityTokenReference(doc);
142 String secRefID = wssConfig.getIdAllocator().createSecureId("STRSAMLId-", secRefSaml);
143 secRefSaml.setID(secRefID);
144
145 org.apache.ws.security.message.token.Reference ref =
146 new org.apache.ws.security.message.token.Reference(doc);
147 ref.setURI("#" + assertion.getId());
148 ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
149 secRefSaml.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
150 secRefSaml.setReference(ref);
151
152 return secRefSaml;
153 }
154
155
156
157
158
159 private WSSecDKSign createDKSign(
160 Document doc,
161 SecurityTokenReference secRefSaml
162 ) throws WSSecurityException {
163 SecurityTokenReference secToken = new SecurityTokenReference(doc);
164 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
165 cryptoType.setAlias("16c73ab6-b892-458f-abf5-2f875f74882e");
166 X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
167 secToken.setKeyIdentifierThumb(certs[0]);
168
169 WSSecDKSign sigBuilder = new WSSecDKSign();
170 java.security.Key key =
171 crypto.getPrivateKey("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
172 sigBuilder.setExternalKey(key.getEncoded(), secToken.getElement());
173 sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
174 List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>(2);
175 String soapNamespace = WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
176 WSEncryptionPart encP =
177 new WSEncryptionPart(
178 WSConstants.ELEM_BODY,
179 soapNamespace,
180 "Content"
181 );
182 parts.add(encP);
183 encP = new WSEncryptionPart("STRTransform", "", "Element");
184 encP.setId(secRefSaml.getID());
185 encP.setElement(secRefSaml.getElement());
186 parts.add(encP);
187 sigBuilder.setParts(parts);
188
189 return sigBuilder;
190 }
191
192
193
194
195
196
197
198
199 private List<WSSecurityEngineResult> verify(Document doc) throws Exception {
200 List<WSSecurityEngineResult> results =
201 secEngine.processSecurityHeader(doc, null, callbackHandler, crypto);
202 String outputString =
203 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
204 assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
205 return results;
206 }
207
208 }