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  package org.apache.wss4j.dom.message;
20  
21  import org.apache.wss4j.dom.WSConstants;
22  import org.apache.wss4j.common.ext.WSSecurityException;
23  import org.apache.wss4j.common.util.XMLUtils;
24  import org.apache.wss4j.dom.util.WSSecurityUtil;
25  import org.w3c.dom.Document;
26  import org.w3c.dom.Element;
27  import org.w3c.dom.Node;
28  
29  /**
30   * This class implements WS Security header.
31   *
32   * Setup a Security header with a specified actor and mustunderstand flag.
33   *
34   * The defaults for actor and mustunderstand are: empty <code>actor</code> and
35   * <code>mustunderstand</code> is true.
36   */
37  public class WSSecHeader {
38      private String actor;
39  
40      private boolean mustunderstand = true;
41  
42      private Element securityHeader;
43  
44      private final Document doc;
45  
46      private String wsuPrefix = WSConstants.WSU_PREFIX;
47  
48      /**
49       * Constructor.
50       * @param doc The Document to use when creating the security header
51       */
52      public WSSecHeader(Document doc) {
53          this(null, doc);
54      }
55  
56      /**
57       * Constructor.
58       *
59       * @param actor The actor name of the <code>wsse:Security</code> header
60       * @param doc The Document to use when creating the security header
61       */
62      public WSSecHeader(String actor, Document doc) {
63          this(actor, true, doc);
64      }
65  
66      /**
67       * Constructor.
68       *
69       * @param act The actor name of the <code>wsse:Security</code> header
70       * @param mu Set <code>mustUnderstand</code> to true or false
71       * @param doc The Document to use when creating the security header
72       */
73      public WSSecHeader(String act, boolean mu, Document doc) {
74          actor = act;
75          mustunderstand = mu;
76          this.doc = doc;
77      }
78  
79      /**
80       * set actor name.
81       *
82       * @param act The actor name of the <code>wsse:Security</code> header
83       */
84      public void setActor(String act) {
85          actor = act;
86      }
87  
88      /**
89       * Set the <code>mustUnderstand</code> flag for the
90       * <code>wsse:Security</code> header.
91       *
92       * @param mu Set <code>mustUnderstand</code> to true or false
93       */
94      public void setMustUnderstand(boolean mu) {
95          mustunderstand = mu;
96      }
97  
98      /**
99       * Get the security header document of this instance.
100      *
101      * @return The security header element.
102      */
103     public Document getSecurityHeaderDoc() {
104         return this.doc;
105     }
106 
107     /**
108      * Get the security header element of this instance.
109      *
110      * @return The security header element.
111      */
112     public Element getSecurityHeaderElement() {
113         return securityHeader;
114     }
115 
116     public void setSecurityHeaderElement(Element securityHeaderElement) {
117         this.securityHeader = securityHeaderElement;
118     }
119 
120     /**
121      * Returns whether the security header is empty
122      *
123      * @return true if empty or if there is no security header
124      *         false if non empty security header
125      */
126     public boolean isEmpty() throws WSSecurityException {
127         if (doc == null) {
128             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "empty",
129                                           new Object[] {"The Document of WSSecHeader is null"});
130         }
131         if (securityHeader == null) {
132             securityHeader =
133                 WSSecurityUtil.findWsseSecurityHeaderBlock(
134                     doc, doc.getDocumentElement(), actor, false
135                 );
136         }
137 
138         return securityHeader == null || securityHeader.getFirstChild() == null;
139     }
140 
141     /**
142      * Creates a security header and inserts it as child into the SOAP Envelope.
143      *
144      * Check if a WS Security header block for an actor is already available in
145      * the document. If a header block is found return it, otherwise a new
146      * wsse:Security header block is created and the attributes set
147      *
148      * @return A <code>wsse:Security</code> element
149      */
150     public Element insertSecurityHeader() throws WSSecurityException {
151         //
152         // If there is already a security header in this instance just return it
153         //
154         if (securityHeader != null) {
155             return securityHeader;
156         }
157 
158         if (doc == null) {
159             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "empty",
160                                           new Object[] {"The Document of WSSecHeader is null"});
161         }
162 
163         securityHeader =
164             WSSecurityUtil.findWsseSecurityHeaderBlock(
165                 doc, doc.getDocumentElement(), actor, true
166             );
167 
168         String soapNamespace = WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
169         String soapPrefix =
170             XMLUtils.setNamespace(
171                 securityHeader, soapNamespace, WSConstants.DEFAULT_SOAP_PREFIX
172             );
173 
174         if (actor != null && actor.length() > 0) {
175             String actorLocal = WSConstants.ATTR_ACTOR;
176             if (WSConstants.URI_SOAP12_ENV.equals(soapNamespace)) {
177                 actorLocal = WSConstants.ATTR_ROLE;
178             }
179             securityHeader.setAttributeNS(
180                 soapNamespace,
181                 soapPrefix + ":" + actorLocal,
182                 actor
183             );
184         }
185         if (mustunderstand) {
186             String mustUnderstandLocal = "1";
187             if (WSConstants.URI_SOAP12_ENV.equals(soapNamespace)) {
188                 mustUnderstandLocal = "true";
189             }
190             securityHeader.setAttributeNS(
191                 soapNamespace,
192                 soapPrefix + ":" + WSConstants.ATTR_MUST_UNDERSTAND,
193                 mustUnderstandLocal
194             );
195         }
196         wsuPrefix = XMLUtils.setNamespace(securityHeader, WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
197 
198         return securityHeader;
199     }
200 
201     public void removeSecurityHeader() throws WSSecurityException {
202         if (securityHeader == null) {
203             if (doc == null) {
204                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "empty",
205                                               new Object[] {"The Document of WSSecHeader is null"});
206             }
207 
208             securityHeader =
209                 WSSecurityUtil.findWsseSecurityHeaderBlock(
210                     doc, doc.getDocumentElement(), actor, false
211                 );
212         }
213 
214         if (securityHeader != null) {
215             Node parent = securityHeader.getParentNode();
216             parent.removeChild(securityHeader);
217         }
218     }
219 
220     public String getWsuPrefix() {
221         return wsuPrefix;
222     }
223 
224 }