1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.ws.security.saml;
21  
22  import org.apache.ws.security.WSConstants;
23  import org.apache.ws.security.WSSConfig;
24  import org.apache.ws.security.WSSecurityEngine;
25  import org.apache.ws.security.WSSecurityEngineResult;
26  import org.apache.ws.security.WSSecurityException;
27  import org.apache.ws.security.common.CustomHandler;
28  import org.apache.ws.security.common.CustomSamlAssertionValidator;
29  import org.apache.ws.security.common.SAML1CallbackHandler;
30  import org.apache.ws.security.common.SAML2CallbackHandler;
31  import org.apache.ws.security.common.SAMLElementCallbackHandler;
32  import org.apache.ws.security.common.SOAPUtil;
33  import org.apache.ws.security.handler.RequestData;
34  import org.apache.ws.security.handler.WSHandlerConstants;
35  import org.apache.ws.security.message.WSSecHeader;
36  import org.apache.ws.security.message.WSSecSAMLToken;
37  import org.apache.ws.security.saml.ext.AssertionWrapper;
38  import org.apache.ws.security.saml.ext.SAMLParms;
39  import org.apache.ws.security.saml.ext.bean.SubjectConfirmationDataBean;
40  import org.apache.ws.security.saml.ext.builder.SAML1Constants;
41  import org.apache.ws.security.util.WSSecurityUtil;
42  
43  import org.joda.time.DateTime;
44  import org.opensaml.Configuration;
45  import org.opensaml.common.SAMLObjectBuilder;
46  import org.opensaml.saml2.core.AttributeValue;
47  import org.opensaml.saml2.core.Conditions;
48  import org.opensaml.xml.XMLObjectBuilder;
49  import org.opensaml.xml.XMLObjectBuilderFactory;
50  import org.opensaml.xml.schema.XSAny;
51  import org.w3c.dom.Document;
52  
53  import java.util.Collections;
54  import java.util.List;
55  
56  /**
57   * Test-case for sending and processing an unsigned (sender vouches) SAML Assertion.
58   * 
59   * @author Davanum Srinivas (dims@yahoo.com)
60   */
61  public class SamlTokenTest extends org.junit.Assert {
62      private static final org.apache.commons.logging.Log LOG = 
63          org.apache.commons.logging.LogFactory.getLog(SamlTokenTest.class);
64      private WSSecurityEngine secEngine = new WSSecurityEngine();
65  
66      public SamlTokenTest() {
67          WSSConfig config = WSSConfig.getNewInstance();
68          config.setValidator(WSSecurityEngine.SAML_TOKEN, new CustomSamlAssertionValidator());
69          config.setValidator(WSSecurityEngine.SAML2_TOKEN, new CustomSamlAssertionValidator());
70          secEngine.setWssConfig(config);
71      }
72      
73      /**
74       * Test that creates, sends and processes an unsigned SAML 1.1 authentication assertion.
75       */
76      @org.junit.Test
77      public void testSAML1AuthnAssertion() throws Exception {
78          SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
79          callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
80          callbackHandler.setIssuer("www.example.com");
81          
82          SAMLParms samlParms = new SAMLParms();
83          samlParms.setCallbackHandler(callbackHandler);
84          AssertionWrapper assertion = new AssertionWrapper(samlParms);
85  
86          WSSecSAMLToken wsSign = new WSSecSAMLToken();
87  
88          Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
89          WSSecHeader secHeader = new WSSecHeader();
90          secHeader.insertSecurityHeader(doc);
91          
92          Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
93  
94          if (LOG.isDebugEnabled()) {
95              LOG.debug("SAML 1.1 Authn Assertion (sender vouches):");
96              String outputString = 
97                  org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
98              LOG.debug(outputString);
99          }
100         
101         List<WSSecurityEngineResult> results = verify(unsignedDoc);
102         WSSecurityEngineResult actionResult =
103             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
104         AssertionWrapper receivedAssertion = 
105             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
106         assertTrue(receivedAssertion != null);
107         assertTrue(!receivedAssertion.isSigned());
108         assertTrue(receivedAssertion.getSignatureValue() == null);
109     }
110     
111     /**
112      * Test that creates, sends and processes an unsigned SAML 1 authentication assertion, where
113      * the configuration is loaded from a properties file
114      */
115     @org.junit.Test
116     public void testSAML1AuthnAssertionFromProperties() throws Exception {
117         SAMLIssuer saml = SAMLIssuerFactory.getInstance("saml_sv.properties");
118         AssertionWrapper assertion = saml.newAssertion();
119 
120         WSSecSAMLToken wsSign = new WSSecSAMLToken();
121 
122         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
123         WSSecHeader secHeader = new WSSecHeader();
124         secHeader.insertSecurityHeader(doc);
125         
126         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
127 
128         if (LOG.isDebugEnabled()) {
129             LOG.debug("SAML 1.1 Authn Assertion (sender vouches):");
130             String outputString = 
131                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
132             LOG.debug(outputString);
133         }
134         
135         List<WSSecurityEngineResult> results = verify(unsignedDoc);
136         WSSecurityEngineResult actionResult =
137             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
138         AssertionWrapper receivedAssertion = 
139             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
140         assertTrue(receivedAssertion != null);
141         assertTrue(!receivedAssertion.isSigned());
142     }
143     
144     /**
145      * Test that creates, sends and processes an unsigned SAML 1.1 authentication assertion.
146      * It set a DOM Element on the CallbackHandler rather than creating a set of beans for
147      * AssertionWrapper to parse.
148      */
149     @org.junit.Test
150     public void testSAML1AuthnAssertionViaElement() throws Exception {
151         SAMLElementCallbackHandler callbackHandler = new SAMLElementCallbackHandler();
152         callbackHandler.setIssuer("www.example.com");
153         
154         SAMLParms samlParms = new SAMLParms();
155         samlParms.setCallbackHandler(callbackHandler);
156         AssertionWrapper assertion = new AssertionWrapper(samlParms);
157 
158         WSSecSAMLToken wsSign = new WSSecSAMLToken();
159 
160         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
161         WSSecHeader secHeader = new WSSecHeader();
162         secHeader.insertSecurityHeader(doc);
163         
164         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
165 
166         if (LOG.isDebugEnabled()) {
167             LOG.debug("SAML 1.1 Authn Assertion (sender vouches - from an Element):");
168             String outputString = 
169                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
170             LOG.debug(outputString);
171         }
172         
173         List<WSSecurityEngineResult> results = verify(unsignedDoc);
174         WSSecurityEngineResult actionResult =
175             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
176         AssertionWrapper receivedAssertion = 
177             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
178         assertTrue(receivedAssertion != null);
179         assertTrue(!receivedAssertion.isSigned());
180         assertTrue(receivedAssertion.getSignatureValue() == null);
181     }
182     
183     /**
184      * Test that creates, sends and processes an unsigned SAML 1.1 attribute assertion.
185      */
186     @org.junit.Test
187     public void testSAML1AttrAssertion() throws Exception {
188         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
189         callbackHandler.setStatement(SAML1CallbackHandler.Statement.ATTR);
190         callbackHandler.setIssuer("www.example.com");
191         
192         SAMLParms samlParms = new SAMLParms();
193         samlParms.setCallbackHandler(callbackHandler);
194         AssertionWrapper assertion = new AssertionWrapper(samlParms);
195 
196         WSSecSAMLToken wsSign = new WSSecSAMLToken();
197 
198         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
199         WSSecHeader secHeader = new WSSecHeader();
200         secHeader.insertSecurityHeader(doc);
201         
202         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
203 
204         if (LOG.isDebugEnabled()) {
205             LOG.debug("SAML 1.1 Attr Assertion (sender vouches):");
206             String outputString = 
207                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
208             LOG.debug(outputString);
209         }
210         
211         List<WSSecurityEngineResult> results = verify(unsignedDoc);
212         WSSecurityEngineResult actionResult =
213             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
214         AssertionWrapper receivedAssertion = 
215             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
216         assertTrue(receivedAssertion != null);
217         assertTrue(!receivedAssertion.isSigned());
218     }
219     
220     /**
221      * Test that creates, sends and processes an unsigned SAML 1.1 authorization assertion.
222      */
223     @org.junit.Test
224     public void testSAML1AuthzAssertion() throws Exception {
225         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
226         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHZ);
227         callbackHandler.setIssuer("www.example.com");
228         callbackHandler.setResource("http://resource.org");
229         
230         SAMLParms samlParms = new SAMLParms();
231         samlParms.setCallbackHandler(callbackHandler);
232         AssertionWrapper assertion = new AssertionWrapper(samlParms);
233 
234         WSSecSAMLToken wsSign = new WSSecSAMLToken();
235 
236         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
237         WSSecHeader secHeader = new WSSecHeader();
238         secHeader.insertSecurityHeader(doc);
239         
240         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
241 
242         if (LOG.isDebugEnabled()) {
243             LOG.debug("SAML 1.1 Authz Assertion (sender vouches):");
244             String outputString = 
245                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
246             LOG.debug(outputString);
247         }
248         
249         List<WSSecurityEngineResult> results = verify(unsignedDoc);
250         WSSecurityEngineResult actionResult =
251             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
252         AssertionWrapper receivedAssertion = 
253             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
254         assertTrue(receivedAssertion != null);
255         assertTrue(!receivedAssertion.isSigned());
256     }
257     
258     /**
259      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion.
260      */
261     @org.junit.Test
262     public void testSAML2AuthnAssertion() throws Exception {
263         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
264         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
265         callbackHandler.setIssuer("www.example.com");
266         
267         SAMLParms samlParms = new SAMLParms();
268         samlParms.setCallbackHandler(callbackHandler);
269         AssertionWrapper assertion = new AssertionWrapper(samlParms);
270 
271         WSSecSAMLToken wsSign = new WSSecSAMLToken();
272 
273         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
274         WSSecHeader secHeader = new WSSecHeader();
275         secHeader.insertSecurityHeader(doc);
276         
277         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
278 
279         if (LOG.isDebugEnabled()) {
280             LOG.debug("SAML 2 Authn Assertion (sender vouches):");
281             String outputString = 
282                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
283             LOG.debug(outputString);
284         }
285         
286         List<WSSecurityEngineResult> results = verify(unsignedDoc);
287         WSSecurityEngineResult actionResult =
288             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
289         AssertionWrapper receivedAssertion = 
290             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
291         assertTrue(receivedAssertion != null);
292         assertTrue(!receivedAssertion.isSigned());
293     }
294     
295     /**
296      * Test that creates, sends and processes an unsigned SAML 2 attribute assertion.
297      */
298     @org.junit.Test
299     public void testSAML2AttrAssertion() throws Exception {
300         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
301         callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
302         callbackHandler.setIssuer("www.example.com");
303         
304         SAMLParms samlParms = new SAMLParms();
305         samlParms.setCallbackHandler(callbackHandler);
306         AssertionWrapper assertion = new AssertionWrapper(samlParms);
307 
308         WSSecSAMLToken wsSign = new WSSecSAMLToken();
309 
310         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
311         WSSecHeader secHeader = new WSSecHeader();
312         secHeader.insertSecurityHeader(doc);
313         
314         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
315 
316         if (LOG.isDebugEnabled()) {
317             LOG.debug("SAML 2 Attr Assertion (sender vouches):");
318             String outputString = 
319                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
320             LOG.debug(outputString);
321         }
322         
323         List<WSSecurityEngineResult> results = verify(unsignedDoc);
324         WSSecurityEngineResult actionResult =
325             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
326         AssertionWrapper receivedAssertion = 
327             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
328         assertTrue(receivedAssertion != null);
329         assertTrue(!receivedAssertion.isSigned());
330     }
331     
332     /**
333      * Test that creates, sends and processes an unsigned SAML 2 authorization assertion.
334      */
335     @org.junit.Test
336     public void testSAML2AuthzAssertion() throws Exception {
337         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
338         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHZ);
339         callbackHandler.setIssuer("www.example.com");
340         callbackHandler.setResource("http://resource.org");
341         
342         SAMLParms samlParms = new SAMLParms();
343         samlParms.setCallbackHandler(callbackHandler);
344         AssertionWrapper assertion = new AssertionWrapper(samlParms);
345 
346         WSSecSAMLToken wsSign = new WSSecSAMLToken();
347 
348         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
349         WSSecHeader secHeader = new WSSecHeader();
350         secHeader.insertSecurityHeader(doc);
351         
352         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
353 
354         if (LOG.isDebugEnabled()) {
355             LOG.debug("SAML 2 Authz Assertion (sender vouches):");
356             String outputString = 
357                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
358             LOG.debug(outputString);
359         }
360         
361         List<WSSecurityEngineResult> results = verify(unsignedDoc);
362         WSSecurityEngineResult actionResult =
363             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
364         AssertionWrapper receivedAssertion = 
365             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
366         assertTrue(receivedAssertion != null);
367         assertTrue(!receivedAssertion.isSigned());
368     }
369 
370     /**
371      * This test checks that an unsigned SAML1 sender-vouches authentication assertion
372      * can be created by the WSHandler implementation 
373      */
374     @org.junit.Test
375     public void testSaml1Action() throws Exception {
376         final WSSConfig cfg = WSSConfig.getNewInstance();
377         final int action = WSConstants.ST_UNSIGNED;
378         final RequestData reqData = new RequestData();
379         reqData.setWssConfig(cfg);
380         java.util.Map<String, Object> config = new java.util.TreeMap<String, Object>();
381         config.put(WSHandlerConstants.SAML_PROP_FILE, "saml_sv.properties");
382         reqData.setMsgContext(config);
383         
384         final java.util.List<Integer> actions = new java.util.ArrayList<Integer>();
385         actions.add(Integer.valueOf(action));
386         final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
387         CustomHandler handler = new CustomHandler();
388         handler.send(
389             action, 
390             doc, 
391             reqData, 
392             actions,
393             true
394         );
395         String outputString = 
396             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
397         if (LOG.isDebugEnabled()) {
398             LOG.debug("Unsigned SAML 1.1 authentication assertion via an Action:");
399             LOG.debug(outputString);
400         }
401         assertFalse (outputString.contains("Signature"));
402         
403         List<WSSecurityEngineResult> results = verify(doc);
404         WSSecurityEngineResult actionResult =
405             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
406         AssertionWrapper receivedAssertion = 
407             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
408         assertTrue(receivedAssertion != null);
409         assertTrue(!receivedAssertion.isSigned());
410     }
411     
412     /**
413      * Test that creates, sends and processes an unsigned SAML 1.1 authentication assertion.
414      * The issuer is different from what the custom Validator is expecting, so it throws an
415      * exception.
416      */
417     @org.junit.Test
418     public void testSAML1AuthnBadIssuerAssertion() throws Exception {
419         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
420         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
421         callbackHandler.setIssuer("www.example2.com");
422         
423         SAMLParms samlParms = new SAMLParms();
424         samlParms.setCallbackHandler(callbackHandler);
425         AssertionWrapper assertion = new AssertionWrapper(samlParms);
426 
427         WSSecSAMLToken wsSign = new WSSecSAMLToken();
428 
429         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
430         WSSecHeader secHeader = new WSSecHeader();
431         secHeader.insertSecurityHeader(doc);
432         
433         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
434 
435         if (LOG.isDebugEnabled()) {
436             LOG.debug("SAML 1.1 Authn Assertion (sender vouches):");
437             String outputString = 
438                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
439             LOG.debug(outputString);
440         }
441         
442         try {
443             verify(unsignedDoc);
444             fail("Failure expected on a bad issuer");
445         } catch (WSSecurityException ex) {
446             // expected
447         }
448     }
449     
450     /**
451      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion.
452      * The issuer is different from what the custom Validator is expecting, so it throws an
453      * exception.
454      */
455     @org.junit.Test
456     public void testSAML2AuthnBadIssuerAssertion() throws Exception {
457         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
458         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
459         callbackHandler.setIssuer("www.example2.com");
460         
461         SAMLParms samlParms = new SAMLParms();
462         samlParms.setCallbackHandler(callbackHandler);
463         AssertionWrapper assertion = new AssertionWrapper(samlParms);
464 
465         WSSecSAMLToken wsSign = new WSSecSAMLToken();
466 
467         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
468         WSSecHeader secHeader = new WSSecHeader();
469         secHeader.insertSecurityHeader(doc);
470         
471         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
472 
473         if (LOG.isDebugEnabled()) {
474             LOG.debug("SAML 2 Authn Assertion (sender vouches):");
475             String outputString = 
476                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
477             LOG.debug(outputString);
478         }
479         
480         try {
481             verify(unsignedDoc);
482             fail("Failure expected on a bad issuer");
483         } catch (WSSecurityException ex) {
484             // expected
485         }
486     }
487     
488     /**
489      * Test that creates, sends and processes an unsigned SAML 1.1 authentication assertion with
490      * a user-specified SubjectNameIDFormat.
491      */
492     @org.junit.Test
493     public void testSAML1SubjectNameIDFormat() throws Exception {
494         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
495         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
496         callbackHandler.setIssuer("www.example.com");
497         callbackHandler.setSubjectNameIDFormat(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS);
498         
499         SAMLParms samlParms = new SAMLParms();
500         samlParms.setCallbackHandler(callbackHandler);
501         AssertionWrapper assertion = new AssertionWrapper(samlParms);
502 
503         WSSecSAMLToken wsSign = new WSSecSAMLToken();
504 
505         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
506         WSSecHeader secHeader = new WSSecHeader();
507         secHeader.insertSecurityHeader(doc);
508         
509         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
510 
511         String outputString = 
512             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
513         if (LOG.isDebugEnabled()) {
514             LOG.debug("SAML 1.1 Authn Assertion (sender vouches):");
515             LOG.debug(outputString);
516         }
517         assertTrue(outputString.contains(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS));
518         
519         List<WSSecurityEngineResult> results = verify(unsignedDoc);
520         WSSecurityEngineResult actionResult =
521             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
522         AssertionWrapper receivedAssertion = 
523             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
524         assertTrue(receivedAssertion != null);
525         assertTrue(!receivedAssertion.isSigned());
526     }
527     
528     /**
529      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion with
530      * a user-specified SubjectNameIDFormat.
531      */
532     @org.junit.Test
533     public void testSAML2SubjectNameIDFormat() throws Exception {
534         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
535         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
536         callbackHandler.setIssuer("www.example.com");
537         callbackHandler.setSubjectNameIDFormat(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS);
538         
539         SAMLParms samlParms = new SAMLParms();
540         samlParms.setCallbackHandler(callbackHandler);
541         AssertionWrapper assertion = new AssertionWrapper(samlParms);
542 
543         WSSecSAMLToken wsSign = new WSSecSAMLToken();
544 
545         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
546         WSSecHeader secHeader = new WSSecHeader();
547         secHeader.insertSecurityHeader(doc);
548         
549         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
550 
551         String outputString = 
552             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
553         if (LOG.isDebugEnabled()) {
554             LOG.debug("SAML 2 Authn Assertion (sender vouches):");
555             LOG.debug(outputString);
556         }
557         assertTrue(outputString.contains(SAML1Constants.NAMEID_FORMAT_EMAIL_ADDRESS));
558         
559         List<WSSecurityEngineResult> results = verify(unsignedDoc);
560         WSSecurityEngineResult actionResult =
561             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
562         AssertionWrapper receivedAssertion = 
563             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
564         assertTrue(receivedAssertion != null);
565         assertTrue(!receivedAssertion.isSigned());
566     }
567     
568     /**
569      * Test that creates, sends and processes an unsigned SAML 1.1 authentication assertion with
570      * a user-specified SubjectLocality statement.
571      */
572     @org.junit.Test
573     public void testSAML1SubjectLocality() throws Exception {
574         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
575         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
576         callbackHandler.setIssuer("www.example.com");
577         callbackHandler.setSubjectLocality("12.34.56.780", "test-dns");
578         
579         SAMLParms samlParms = new SAMLParms();
580         samlParms.setCallbackHandler(callbackHandler);
581         AssertionWrapper assertion = new AssertionWrapper(samlParms);
582 
583         WSSecSAMLToken wsSign = new WSSecSAMLToken();
584 
585         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
586         WSSecHeader secHeader = new WSSecHeader();
587         secHeader.insertSecurityHeader(doc);
588         
589         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
590 
591         String outputString = 
592             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
593         if (LOG.isDebugEnabled()) {
594             LOG.debug("SAML 1.1 Authn Assertion (sender vouches):");
595             LOG.debug(outputString);
596         }
597         assertTrue(outputString.contains("12.34.56.780"));
598         assertTrue(outputString.contains("test-dns"));
599         
600         List<WSSecurityEngineResult> results = verify(unsignedDoc);
601         WSSecurityEngineResult actionResult =
602             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
603         AssertionWrapper receivedAssertion = 
604             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
605         assertTrue(receivedAssertion != null);
606         assertTrue(!receivedAssertion.isSigned());
607     }
608     
609     /**
610      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion with
611      * a user-specified SubjectLocality statement.
612      */
613     @org.junit.Test
614     public void testSAML2SubjectLocality() throws Exception {
615         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
616         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
617         callbackHandler.setIssuer("www.example.com");
618         callbackHandler.setSubjectLocality("12.34.56.780", "test-dns");
619         
620         SAMLParms samlParms = new SAMLParms();
621         samlParms.setCallbackHandler(callbackHandler);
622         AssertionWrapper assertion = new AssertionWrapper(samlParms);
623 
624         WSSecSAMLToken wsSign = new WSSecSAMLToken();
625 
626         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
627         WSSecHeader secHeader = new WSSecHeader();
628         secHeader.insertSecurityHeader(doc);
629         
630         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
631 
632         String outputString = 
633             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
634         if (LOG.isDebugEnabled()) {
635             LOG.debug("SAML 2 Authn Assertion (sender vouches):");
636             LOG.debug(outputString);
637         }
638         assertTrue(outputString.contains("12.34.56.780"));
639         assertTrue(outputString.contains("test-dns"));
640         
641         List<WSSecurityEngineResult> results = verify(unsignedDoc);
642         WSSecurityEngineResult actionResult =
643             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
644         AssertionWrapper receivedAssertion = 
645             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
646         assertTrue(receivedAssertion != null);
647         assertTrue(!receivedAssertion.isSigned());
648     }
649     
650     /**
651      * Test that creates, sends and processes an unsigned SAML 1.1 authorization assertion
652      * with a Resource URI.
653      */
654     @org.junit.Test
655     public void testSAML1Resource() throws Exception {
656         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
657         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHZ);
658         callbackHandler.setIssuer("www.example.com");
659         callbackHandler.setResource("http://resource.org");
660         
661         SAMLParms samlParms = new SAMLParms();
662         samlParms.setCallbackHandler(callbackHandler);
663         AssertionWrapper assertion = new AssertionWrapper(samlParms);
664 
665         WSSecSAMLToken wsSign = new WSSecSAMLToken();
666 
667         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
668         WSSecHeader secHeader = new WSSecHeader();
669         secHeader.insertSecurityHeader(doc);
670         
671         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
672 
673         String outputString = 
674             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
675         if (LOG.isDebugEnabled()) {
676             LOG.debug("SAML 1.1 Authz Assertion (sender vouches):");
677             LOG.debug(outputString);
678         }
679         assertTrue(outputString.contains("http://resource.org"));
680         
681         List<WSSecurityEngineResult> results = verify(unsignedDoc);
682         WSSecurityEngineResult actionResult =
683             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
684         AssertionWrapper receivedAssertion = 
685             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
686         assertTrue(receivedAssertion != null);
687         assertTrue(!receivedAssertion.isSigned());
688     }
689     
690     /**
691      * Test that creates, sends and processes an unsigned SAML 2 attribute assertion. The attributeValue
692      * has a custom XMLObject (not a String) value.
693      */
694     @org.junit.Test
695     @SuppressWarnings("unchecked")
696     public void testSAML2AttrAssertionCustomAttribute() throws Exception {
697         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
698         callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
699         callbackHandler.setIssuer("www.example.com");
700         
701         // Create and add a custom Attribute (conditions Object)
702         XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
703         
704         SAMLObjectBuilder<Conditions> conditionsV2Builder = 
705                 (SAMLObjectBuilder<Conditions>)builderFactory.getBuilder(Conditions.DEFAULT_ELEMENT_NAME);
706         Conditions conditions = conditionsV2Builder.buildObject();
707         DateTime newNotBefore = new DateTime();
708         conditions.setNotBefore(newNotBefore);
709         conditions.setNotOnOrAfter(newNotBefore.plusMinutes(5));
710         
711         XMLObjectBuilder<XSAny> xsAnyBuilder = builderFactory.getBuilder(XSAny.TYPE_NAME);
712         XSAny attributeValue = xsAnyBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME);
713         attributeValue.getUnknownXMLObjects().add(conditions);
714         
715         callbackHandler.setCustomAttributeValues(Collections.singletonList(attributeValue));
716 
717         SAMLParms samlParms = new SAMLParms();
718         samlParms.setCallbackHandler(callbackHandler);
719         AssertionWrapper assertion = new AssertionWrapper(samlParms);
720 
721         WSSecSAMLToken wsSign = new WSSecSAMLToken();
722 
723         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
724         WSSecHeader secHeader = new WSSecHeader();
725         secHeader.insertSecurityHeader(doc);
726         
727         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
728 
729         if (LOG.isDebugEnabled()) {
730             LOG.debug("SAML 2 Attr Assertion (sender vouches):");
731             String outputString = 
732                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
733             LOG.debug(outputString);
734         }
735         
736         List<WSSecurityEngineResult> results = verify(unsignedDoc);
737         WSSecurityEngineResult actionResult =
738             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
739         AssertionWrapper receivedAssertion = 
740             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
741         assertTrue(receivedAssertion != null);
742         assertTrue(!receivedAssertion.isSigned());
743     }
744     
745     /**
746      * Test that creates, sends and processes an unsigned SAML 2 authentication assertion with
747      * SubjectConfirmationData information.
748      */
749     @org.junit.Test
750     public void testSAML2SubjectConfirmationData() throws Exception {
751         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
752         callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
753         callbackHandler.setIssuer("www.example.com");
754         
755         SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();
756         subjectConfirmationData.setAddress("http://apache.org");
757         subjectConfirmationData.setInResponseTo("12345");
758         subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
759         subjectConfirmationData.setRecipient("http://recipient.apache.org");
760         callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
761         
762         SAMLParms samlParms = new SAMLParms();
763         samlParms.setCallbackHandler(callbackHandler);
764         AssertionWrapper assertion = new AssertionWrapper(samlParms);
765 
766         WSSecSAMLToken wsSign = new WSSecSAMLToken();
767 
768         Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
769         WSSecHeader secHeader = new WSSecHeader();
770         secHeader.insertSecurityHeader(doc);
771         
772         Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
773 
774         String outputString = 
775             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
776         if (LOG.isDebugEnabled()) {
777             LOG.debug("SAML 2 Authn Assertion (sender vouches):");
778             LOG.debug(outputString);
779         }
780         assertTrue(outputString.contains("http://recipient.apache.org"));
781         
782         List<WSSecurityEngineResult> results = verify(unsignedDoc);
783         WSSecurityEngineResult actionResult =
784             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
785         AssertionWrapper receivedAssertion = 
786             (AssertionWrapper) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
787         assertTrue(receivedAssertion != null);
788         assertTrue(!receivedAssertion.isSigned());
789     }
790     
791     /**
792      * Verifies the soap envelope
793      * <p/>
794      * 
795      * @param envelope 
796      * @throws Exception Thrown when there is a problem in verification
797      */
798     private List<WSSecurityEngineResult> verify(Document doc) throws Exception {
799         List<WSSecurityEngineResult> results = 
800             secEngine.processSecurityHeader(doc, null, null, null);
801         String outputString = 
802             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
803         assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
804         return results;
805     }
806     
807 }