1 /*
2 * Copyright 2004,2005 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.rampart;
18
19 import org.apache.axiom.om.OMElement;
20 import org.apache.axis2.AxisFault;
21 import org.apache.axis2.Constants;
22 import org.apache.axis2.addressing.AddressingConstants;
23 import org.apache.axis2.addressing.AddressingConstants.Final;
24 import org.apache.axis2.addressing.AddressingConstants.Submission;
25 import org.apache.axis2.context.MessageContext;
26 import org.apache.axis2.context.OperationContext;
27 import org.apache.axis2.util.XMLUtils;
28 import org.apache.axis2.wsdl.WSDLConstants;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.rahas.RahasConstants;
32 import org.apache.rahas.TrustUtil;
33 import org.apache.rampart.builder.AsymmetricBindingBuilder;
34 import org.apache.rampart.builder.SymmetricBindingBuilder;
35 import org.apache.rampart.builder.TransportBindingBuilder;
36 import org.apache.rampart.policy.RampartPolicyData;
37 import org.apache.rampart.policy.model.OptimizePartsConfig;
38 import org.apache.rampart.util.Axis2Util;
39 import org.apache.rampart.util.MessageOptimizer;
40 import org.apache.rampart.util.RampartUtil;
41 import org.apache.ws.secpolicy.WSSPolicyException;
42 import org.apache.ws.security.WSSecurityException;
43 import org.apache.ws.security.handler.WSHandlerConstants;
44 import org.apache.ws.security.message.WSSecHeader;
45 import org.apache.ws.security.message.token.SecurityContextToken;
46 import org.w3c.dom.Document;
47 import org.w3c.dom.Element;
48 import org.w3c.dom.Node;
49
50 import javax.xml.namespace.QName;
51
52 public class MessageBuilder {
53
54 private static Log log = LogFactory.getLog(MessageBuilder.class);
55
56 public void build(MessageContext msgCtx) throws WSSPolicyException,
57 RampartException, WSSecurityException, AxisFault {
58
59 Axis2Util.useDOOM(true);
60
61 RampartMessageData rmd = new RampartMessageData(msgCtx, true);
62
63
64 RampartPolicyData rpd = rmd.getPolicyData();
65 if(rpd == null || isSecurityValidationFault(msgCtx) ||
66 !RampartUtil.isSecHeaderRequired(rpd, rmd.isInitiator(),false)) {
67
68 Document doc = rmd.getDocument();
69 WSSecHeader secHeader = rmd.getSecHeader();
70
71 if ( secHeader != null && secHeader.isEmpty(doc) ) {
72 secHeader.removeSecurityHeader(doc);
73 }
74
75 return;
76 }
77
78 //Copy the RECV_RESULTS if available
79 if(!rmd.isInitiator()) {
80 OperationContext opCtx = msgCtx.getOperationContext();
81 MessageContext inMsgCtx;
82 if(opCtx != null &&
83 (inMsgCtx = opCtx.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE)) != null) {
84 msgCtx.setProperty(WSHandlerConstants.RECV_RESULTS,
85 inMsgCtx.getProperty(WSHandlerConstants.RECV_RESULTS));
86 }
87 }
88
89
90 String isCancelreq = (String)msgCtx.getProperty(RampartMessageData.CANCEL_REQUEST);
91 if(isCancelreq != null && Constants.VALUE_TRUE.equals(isCancelreq)) {
92 try {
93
94 String cancelAction = TrustUtil.getWSTNamespace(rmd.getWstVersion()) + RahasConstants.RST_ACTION_CANCEL_SCT;
95 //Set action
96 msgCtx.getOptions().setAction(cancelAction);
97
98 //Change the wsa:Action header
99 String wsaNs = Final.WSA_NAMESPACE;
100 Object addressingVersionFromCurrentMsgCtxt = msgCtx.getProperty(AddressingConstants.WS_ADDRESSING_VERSION);
101 if (Submission.WSA_NAMESPACE.equals(addressingVersionFromCurrentMsgCtxt)) {
102 wsaNs = Submission.WSA_NAMESPACE;
103 }
104 OMElement header = msgCtx.getEnvelope().getHeader();
105 if(header != null) {
106 OMElement actionElem = header.getFirstChildWithName(new QName(wsaNs, AddressingConstants.WSA_ACTION));
107 if(actionElem != null) {
108 actionElem.setText(cancelAction);
109 }
110 }
111
112 //set payload to a cancel request
113 String ctxIdKey = RampartUtil.getContextIdentifierKey(msgCtx);
114 String tokenId = (String)RampartUtil.getContextMap(msgCtx).get(ctxIdKey);
115
116 if(tokenId != null && RampartUtil.isTokenValid(rmd, tokenId)) {
117 OMElement bodyElem = msgCtx.getEnvelope().getBody();
118 OMElement child = bodyElem.getFirstElement();
119 SecurityContextToken sct = new SecurityContextToken(
120 (Element) rmd.getTokenStorage().getToken(tokenId)
121 .getToken());
122 OMElement newChild = TrustUtil.createCancelRequest(sct
123 .getIdentifier(), rmd.getWstVersion());
124 Element newDomChild = XMLUtils.toDOM(newChild);
125 Node importedNode = rmd.getDocument().importNode((Element) newDomChild, true);
126 ((Element) bodyElem).replaceChild(importedNode, (Element) child);
127 } else {
128 throw new RampartException("tokenToBeCancelledInvalid");
129 }
130
131 } catch (Exception e) {
132 e.printStackTrace();
133 throw new RampartException("errorInTokenCancellation");
134 }
135 }
136
137 if(rpd.isTransportBinding()) {
138 log.debug("Building transport binding");
139 TransportBindingBuilder building = new TransportBindingBuilder();
140 building.build(rmd);
141 } else if(rpd.isSymmetricBinding()) {
142 log.debug("Building SymmetricBinding");
143 SymmetricBindingBuilder builder = new SymmetricBindingBuilder();
144 builder.build(rmd);
145 } else {
146 AsymmetricBindingBuilder builder = new AsymmetricBindingBuilder();
147 builder.build(rmd);
148 }
149
150 //TODO remove following check, we don't need this check here as we do a check to see whether
151 // security header required
152
153 Document doc = rmd.getDocument();
154 WSSecHeader secHeader = rmd.getSecHeader();
155
156 if ( secHeader != null && secHeader.isEmpty(doc) ) {
157 secHeader.removeSecurityHeader(doc);
158 }
159
160 /*
161 * Checking whether MTOMSerializable is there. If so set optimizeElement.
162 * */
163 if(rpd.isMTOMSerialize()){
164 msgCtx.setProperty(Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE);
165 OptimizePartsConfig config= rpd.getOptimizePartsConfig();
166 if(config != null){
167 MessageOptimizer.optimize(msgCtx.getEnvelope(), config.getExpressions(), config.getNamespaces());
168 }
169 }
170
171 }
172
173 private boolean isSecurityValidationFault(MessageContext msgCtx) throws AxisFault {
174
175 OperationContext opCtx = msgCtx.getOperationContext();
176 MessageContext inMsgCtx;
177 if(opCtx != null &&
178 (inMsgCtx = opCtx.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE)) != null) {
179 Boolean secErrorFlag = (Boolean) inMsgCtx.getProperty(RampartConstants.SEC_FAULT);
180
181 if (secErrorFlag != null && secErrorFlag.equals(Boolean.TRUE)) {
182 return true;
183 }
184 }
185
186 return false;
187 }
188 }