View Javadoc
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.wss4j.dom.saml;
21  
22  import java.util.ArrayList;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.TreeMap;
26  
27  import org.apache.wss4j.common.WSEncryptionPart;
28  import org.apache.wss4j.common.crypto.Crypto;
29  import org.apache.wss4j.common.crypto.CryptoFactory;
30  import org.apache.wss4j.common.saml.SAMLCallback;
31  import org.apache.wss4j.common.saml.SAMLUtil;
32  import org.apache.wss4j.common.saml.SamlAssertionWrapper;
33  import org.apache.wss4j.common.saml.builder.SAML1Constants;
34  import org.apache.wss4j.common.util.SOAPUtil;
35  import org.apache.wss4j.common.util.XMLUtils;
36  import org.apache.wss4j.dom.WSConstants;
37  import org.apache.wss4j.dom.common.CustomHandler;
38  import org.apache.wss4j.dom.common.SAML1CallbackHandler;
39  
40  import org.apache.wss4j.dom.engine.WSSConfig;
41  import org.apache.wss4j.dom.engine.WSSecurityEngine;
42  import org.apache.wss4j.dom.handler.HandlerAction;
43  import org.apache.wss4j.dom.handler.RequestData;
44  import org.apache.wss4j.dom.handler.WSHandlerConstants;
45  import org.apache.wss4j.dom.handler.WSHandlerResult;
46  import org.apache.wss4j.dom.message.WSSecHeader;
47  import org.apache.wss4j.dom.message.WSSecSignature;
48  
49  import org.junit.jupiter.api.Test;
50  import org.w3c.dom.Document;
51  import org.w3c.dom.Element;
52  
53  import static org.junit.jupiter.api.Assertions.assertTrue;
54  
55  /**
56   */
57  public class SamlTokenCustomSignatureTest {
58      private static final org.slf4j.Logger LOG =
59          org.slf4j.LoggerFactory.getLogger(SamlTokenCustomSignatureTest.class);
60  
61      private Crypto crypto;
62  
63      public SamlTokenCustomSignatureTest() throws Exception {
64          WSSConfig.init();
65          crypto = CryptoFactory.getInstance("crypto.properties");
66      }
67  
68      @Test
69      public void testAddSAML1AndSign() throws Exception {
70          SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
71          callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
72          callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
73          callbackHandler.setIssuer("www.example.com");
74  
75          SAMLCallback samlCallback = new SAMLCallback();
76          SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
77          SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
78  
79          Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
80          Element assertionElement = samlAssertion.toDOM(doc);
81  
82          WSSecHeader secHeader = new WSSecHeader(doc);
83          secHeader.insertSecurityHeader();
84          secHeader.getSecurityHeaderElement().appendChild(assertionElement);
85  
86          WSSecSignature sign = new WSSecSignature(secHeader);
87          sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
88          sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
89  
90          WSEncryptionPart encP =
91              new WSEncryptionPart(
92                  "Assertion",
93                  "urn:oasis:names:tc:SAML:1.0:assertion",
94                  "Element");
95          encP.setRequired(false);
96          sign.getParts().add(encP);
97  
98          Document signedDoc = sign.build(crypto);
99  
100         if (LOG.isDebugEnabled()) {
101             String outputString = XMLUtils.prettyDocumentToString(doc);
102             LOG.debug(outputString);
103         }
104 
105         verify(signedDoc);
106     }
107 
108     @Test
109     public void testAddSAML1AndSignAction() throws Exception {
110         SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
111         callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
112         callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
113         callbackHandler.setIssuer("www.example.com");
114 
115         final WSSConfig cfg = WSSConfig.getNewInstance();
116         final RequestData reqData = new RequestData();
117         reqData.setWssConfig(cfg);
118         reqData.setUsername("16c73ab6-b892-458f-abf5-2f875f74882e");
119 
120         Map<String, Object> config = new TreeMap<>();
121         config.put(WSHandlerConstants.SIG_PROP_FILE, "crypto.properties");
122         config.put("password", "security");
123         config.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
124         config.put(
125             WSHandlerConstants.SIGNATURE_PARTS,
126             "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion"
127         );
128         config.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
129         reqData.setMsgContext(config);
130 
131         final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
132         CustomHandler handler = new CustomHandler();
133 
134         List<HandlerAction> actions = new ArrayList<>();
135         HandlerAction action = new HandlerAction(WSConstants.ST_UNSIGNED);
136         actions.add(action);
137         action = new HandlerAction(WSConstants.SIGN);
138         actions.add(action);
139 
140         handler.send(
141             doc,
142             reqData,
143             actions,
144             true
145         );
146         String outputString =
147             XMLUtils.prettyDocumentToString(doc);
148         if (LOG.isDebugEnabled()) {
149             LOG.debug("Signed message:");
150             LOG.debug(outputString);
151         }
152 
153         verify(doc);
154     }
155 
156     /**
157      * Verifies the soap envelope
158      *
159      * @param doc
160      * @throws Exception Thrown when there is a problem in verification
161      */
162     private WSHandlerResult verify(Document doc) throws Exception {
163         WSSecurityEngine secEngine = new WSSecurityEngine();
164         RequestData requestData = new RequestData();
165         requestData.setDecCrypto(crypto);
166         requestData.setSigVerCrypto(crypto);
167         requestData.setValidateSamlSubjectConfirmation(false);
168 
169         WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
170         String outputString = XMLUtils.prettyDocumentToString(doc);
171         assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
172         return results;
173     }
174 
175 }