1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.dom.saml;
21
22 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
23 import org.apache.wss4j.common.util.SOAPUtil;
24 import org.apache.wss4j.dom.WSConstants;
25 import org.apache.wss4j.dom.WSDataRef;
26 import org.apache.wss4j.dom.common.CustomHandler;
27 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
28 import org.apache.wss4j.dom.common.SAML1CallbackHandler;
29 import org.apache.wss4j.dom.common.SAML2CallbackHandler;
30
31 import org.apache.wss4j.dom.engine.WSSConfig;
32 import org.apache.wss4j.dom.engine.WSSecurityEngine;
33 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
34 import org.apache.wss4j.common.crypto.Crypto;
35 import org.apache.wss4j.common.crypto.CryptoFactory;
36 import org.apache.wss4j.common.saml.SAMLCallback;
37 import org.apache.wss4j.common.saml.SAMLUtil;
38 import org.apache.wss4j.common.saml.builder.SAML1Constants;
39 import org.apache.wss4j.common.saml.builder.SAML2Constants;
40 import org.apache.wss4j.common.util.XMLUtils;
41 import org.apache.wss4j.dom.handler.RequestData;
42 import org.apache.wss4j.dom.handler.WSHandlerConstants;
43 import org.apache.wss4j.dom.handler.WSHandlerResult;
44 import org.apache.wss4j.dom.message.WSSecHeader;
45
46 import org.junit.jupiter.api.Test;
47 import org.w3c.dom.Document;
48
49 import java.util.Collections;
50 import java.util.List;
51
52 import javax.security.auth.callback.CallbackHandler;
53
54 import static org.junit.jupiter.api.Assertions.assertEquals;
55 import static org.junit.jupiter.api.Assertions.assertFalse;
56 import static org.junit.jupiter.api.Assertions.assertNotNull;
57 import static org.junit.jupiter.api.Assertions.assertTrue;
58
59
60
61
62 public class SamlTokenSVTest {
63 private static final org.slf4j.Logger LOG =
64 org.slf4j.LoggerFactory.getLogger(SamlTokenSVTest.class);
65 private WSSecurityEngine secEngine = new WSSecurityEngine();
66 private CallbackHandler callbackHandler = new KeystoreCallbackHandler();
67 private Crypto crypto;
68
69 public SamlTokenSVTest() throws Exception {
70 WSSConfig.init();
71 crypto = CryptoFactory.getInstance("crypto.properties");
72 }
73
74
75
76
77 @Test
78 @SuppressWarnings("unchecked")
79 public void testSAML1AuthnAssertion() throws Exception {
80 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
81 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
82 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
83 callbackHandler.setIssuer("www.example.com");
84
85 SAMLCallback samlCallback = new SAMLCallback();
86 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
87 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
88
89 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
90 WSSecHeader secHeader = new WSSecHeader(doc);
91 secHeader.insertSecurityHeader();
92
93 WSSecSignatureSAML wsSign = new WSSecSignatureSAML(secHeader);
94 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
95
96 Document signedDoc =
97 wsSign.build(
98 null, samlAssertion, crypto, "16c73ab6-b892-458f-abf5-2f875f74882e",
99 "security"
100 );
101
102 if (LOG.isDebugEnabled()) {
103 LOG.debug("SAML 1.1 Authn Assertion (sender vouches):");
104 String outputString =
105 XMLUtils.prettyDocumentToString(signedDoc);
106 LOG.debug(outputString);
107 }
108
109
110 WSHandlerResult results = verify(signedDoc);
111 WSSecurityEngineResult actionResult =
112 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
113 SamlAssertionWrapper receivedSamlAssertion =
114 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
115 assertNotNull(receivedSamlAssertion);
116
117
118 actionResult = results.getActionResults().get(WSConstants.SIGN).get(0);
119 assertNotNull(actionResult);
120 assertFalse(actionResult.isEmpty());
121 final List<WSDataRef> refs =
122 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
123 assertTrue(refs.size() == 2);
124
125 WSDataRef wsDataRef = refs.get(0);
126 String xpath = wsDataRef.getXpath();
127 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
128
129 wsDataRef = refs.get(1);
130 xpath = wsDataRef.getXpath();
131 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml1:Assertion", xpath);
132 }
133
134
135
136
137 @Test
138 @SuppressWarnings("unchecked")
139 public void testSAML1AttrAssertion() throws Exception {
140 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
141 callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
142 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
143 callbackHandler.setIssuer("www.example.com");
144
145 SAMLCallback samlCallback = new SAMLCallback();
146 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
147 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
148
149 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
150 WSSecHeader secHeader = new WSSecHeader(doc);
151 secHeader.insertSecurityHeader();
152
153 WSSecSignatureSAML wsSign = new WSSecSignatureSAML(secHeader);
154 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
155
156 Document signedDoc =
157 wsSign.build(
158 null, samlAssertion, crypto, "16c73ab6-b892-458f-abf5-2f875f74882e",
159 "security"
160 );
161
162 if (LOG.isDebugEnabled()) {
163 LOG.debug("SAML 1.1 Attr Assertion (sender vouches):");
164 String outputString =
165 XMLUtils.prettyDocumentToString(signedDoc);
166 LOG.debug(outputString);
167 }
168
169
170 WSHandlerResult results = verify(signedDoc);
171 WSSecurityEngineResult actionResult =
172 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
173 SamlAssertionWrapper receivedSamlAssertion =
174 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
175 assertNotNull(receivedSamlAssertion);
176
177
178 actionResult = results.getActionResults().get(WSConstants.SIGN).get(0);
179 assertNotNull(actionResult);
180 assertFalse(actionResult.isEmpty());
181 final List<WSDataRef> refs =
182 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
183 assertTrue(refs.size() == 2);
184
185 WSDataRef wsDataRef = refs.get(0);
186 String xpath = wsDataRef.getXpath();
187 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
188
189 wsDataRef = refs.get(1);
190 xpath = wsDataRef.getXpath();
191 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml1:Assertion", xpath);
192 }
193
194
195
196
197 @Test
198 @SuppressWarnings("unchecked")
199 public void testSAML2AuthnAssertion() throws Exception {
200 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
201 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
202 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
203 callbackHandler.setIssuer("www.example.com");
204
205 SAMLCallback samlCallback = new SAMLCallback();
206 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
207 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
208
209 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
210 WSSecHeader secHeader = new WSSecHeader(doc);
211 secHeader.insertSecurityHeader();
212
213 WSSecSignatureSAML wsSign = new WSSecSignatureSAML(secHeader);
214 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
215
216 Document signedDoc =
217 wsSign.build(
218 null, samlAssertion, crypto, "16c73ab6-b892-458f-abf5-2f875f74882e",
219 "security"
220 );
221
222 if (LOG.isDebugEnabled()) {
223 LOG.debug("SAML 2 Authn Assertion (sender vouches):");
224 String outputString =
225 XMLUtils.prettyDocumentToString(signedDoc);
226 LOG.debug(outputString);
227 }
228
229
230 WSHandlerResult results = verify(signedDoc);
231 WSSecurityEngineResult actionResult =
232 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
233 SamlAssertionWrapper receivedSamlAssertion =
234 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
235 assertNotNull(receivedSamlAssertion);
236
237
238 actionResult = results.getActionResults().get(WSConstants.SIGN).get(0);
239 assertNotNull(actionResult);
240 assertFalse(actionResult.isEmpty());
241 final List<WSDataRef> refs =
242 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
243 assertTrue(refs.size() == 2);
244
245 WSDataRef wsDataRef = refs.get(0);
246 String xpath = wsDataRef.getXpath();
247 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
248
249 wsDataRef = refs.get(1);
250 xpath = wsDataRef.getXpath();
251 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml2:Assertion", xpath);
252 }
253
254
255
256
257 @Test
258 @SuppressWarnings("unchecked")
259 public void testSAML2AttrAssertion() throws Exception {
260 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
261 callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
262 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
263 callbackHandler.setIssuer("www.example.com");
264
265 SAMLCallback samlCallback = new SAMLCallback();
266 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
267 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
268
269 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
270 WSSecHeader secHeader = new WSSecHeader(doc);
271 secHeader.insertSecurityHeader();
272
273 WSSecSignatureSAML wsSign = new WSSecSignatureSAML(secHeader);
274 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
275
276 Document signedDoc =
277 wsSign.build(
278 null, samlAssertion, crypto, "16c73ab6-b892-458f-abf5-2f875f74882e",
279 "security"
280 );
281
282 if (LOG.isDebugEnabled()) {
283 LOG.debug("SAML 2 Attr Assertion (sender vouches):");
284 String outputString =
285 XMLUtils.prettyDocumentToString(signedDoc);
286 LOG.debug(outputString);
287 }
288
289
290 WSHandlerResult results = verify(signedDoc);
291 WSSecurityEngineResult actionResult =
292 results.getActionResults().get(WSConstants.ST_UNSIGNED).get(0);
293 SamlAssertionWrapper receivedSamlAssertion =
294 (SamlAssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
295 assertNotNull(receivedSamlAssertion);
296
297
298 actionResult = results.getActionResults().get(WSConstants.SIGN).get(0);
299 assertNotNull(actionResult);
300 assertFalse(actionResult.isEmpty());
301 final List<WSDataRef> refs =
302 (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
303 assertTrue(refs.size() == 2);
304
305 WSDataRef wsDataRef = refs.get(0);
306 String xpath = wsDataRef.getXpath();
307 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
308
309 wsDataRef = refs.get(1);
310 xpath = wsDataRef.getXpath();
311 assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml2:Assertion", xpath);
312 }
313
314
315
316
317
318
319
320 @Test
321 public void testWSS62() throws Exception {
322 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
323 callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
324 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
325 callbackHandler.setIssuer("www.example.com");
326
327 SAMLCallback samlCallback = new SAMLCallback();
328 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
329 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
330
331 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
332 WSSecHeader secHeader = new WSSecHeader(doc);
333 secHeader.insertSecurityHeader();
334
335 WSSecSignatureSAML wsSign = new WSSecSignatureSAML(secHeader);
336 wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
337
338 Document signedDoc =
339 wsSign.build(
340 null, samlAssertion, crypto, "16c73ab6-b892-458f-abf5-2f875f74882e",
341 "security"
342 );
343
344
345
346 final WSSConfig cfg = WSSConfig.getNewInstance();
347 final RequestData reqData = new RequestData();
348 reqData.setWssConfig(cfg);
349 java.util.Map<String, Object> msgContext = new java.util.HashMap<>();
350 msgContext.put(WSHandlerConstants.SIG_VER_PROP_FILE, "crypto.properties");
351 reqData.setMsgContext(msgContext);
352
353 CustomHandler handler = new CustomHandler();
354 handler.receive(Collections.singletonList(WSConstants.ST_SIGNED), reqData);
355
356 secEngine.processSecurityHeader(
357 signedDoc, null, callbackHandler, reqData.getSigVerCrypto(), reqData.getDecCrypto()
358 );
359 }
360
361
362
363
364
365
366
367
368
369 private WSHandlerResult verify(Document doc) throws Exception {
370 WSHandlerResult results =
371 secEngine.processSecurityHeader(doc, null, callbackHandler, crypto);
372 String outputString =
373 XMLUtils.prettyDocumentToString(doc);
374 assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
375 return results;
376 }
377
378 }