/** * Determines if the current message has no response content. The message has no response content * if either: - the request is oneway and the current message is no partial response or an empty * partial response. - the request is not oneway but the current message is an empty partial * response. * * @param message * @return */ private boolean hasNoResponseContent(Message message) { final boolean ow = isOneWay(message); final boolean pr = MessageUtils.isPartialResponse(message); final boolean epr = MessageUtils.isEmptyPartialResponse(message); // REVISIT may need to provide an option to choose other behavior? // old behavior not suppressing any responses => ow && !pr // suppress empty responses for oneway calls => ow && (!pr || epr) // suppress additionally empty responses for decoupled twoway calls => return (ow && (!pr || epr)) || (!ow && epr); }
public void handleMessage(Message msg) { Fault fault = (Fault) msg.getContent(Exception.class); if (fault.getDetail() != null && !MessageUtils.getContextualBoolean(msg, DISABLE_FAULT_MAPPING, false)) { processFaultDetail(fault, msg); setStackTrace(fault, msg); } FaultMode faultMode = FaultMode.UNCHECKED_APPLICATION_FAULT; // Check if the raised exception is declared in the WSDL or by the JAX-RS resource Method m = msg.getExchange().get(Method.class); if (m != null) { Exception e = msg.getContent(Exception.class); for (Class<?> cl : m.getExceptionTypes()) { if (cl.isInstance(e)) { faultMode = FaultMode.CHECKED_APPLICATION_FAULT; break; } } } msg.getExchange().put(FaultMode.class, faultMode); }
protected void handle(Message message) throws SequenceFault, RMException { LOG.entering(getClass().getName(), "handleMessage"); // This message capturing mechanism will need to be changed at some point. // Until then, we keep this interceptor here and utilize the robust // option to avoid the unnecessary message capturing/caching. if (!MessageUtils.isTrue(message.getContextualProperty(Message.ROBUST_ONEWAY))) { InputStream is = message.getContent(InputStream.class); if (is != null) { CachedOutputStream saved = new CachedOutputStream(); try { IOUtils.copy(is, saved); saved.flush(); is.close(); saved.lockOutputStream(); LOG.fine("Capturing the original RM message"); RewindableInputStream ris = RewindableInputStream.makeRewindable(saved.getInputStream()); message.setContent(InputStream.class, ris); message.put(RMMessageConstants.SAVED_CONTENT, ris); } catch (Exception e) { throw new Fault(e); } } } }
/** * Invoked for normal processing of inbound and outbound messages. * * @param message the current message */ public void handleMessage(Message message) { if (!MessageUtils.getContextualBoolean(message, ADDRESSING_DISABLED, false)) { mediate(message, ContextUtils.isFault(message)); } else { // addressing is completely disabled manually, we need to assert the // assertions as the user is in control of those AssertionInfoMap aim = message.get(AssertionInfoMap.class); if (null == aim) { return; } QName[] types = new QName[] { MetadataConstants.ADDRESSING_ASSERTION_QNAME, MetadataConstants.USING_ADDRESSING_2004_QNAME, MetadataConstants.USING_ADDRESSING_2005_QNAME, MetadataConstants.USING_ADDRESSING_2006_QNAME, MetadataConstants.ANON_RESPONSES_ASSERTION_QNAME, MetadataConstants.NON_ANON_RESPONSES_ASSERTION_QNAME, MetadataConstants.ANON_RESPONSES_ASSERTION_QNAME_0705, MetadataConstants.NON_ANON_RESPONSES_ASSERTION_QNAME_0705 }; for (QName type : types) { assertAssertion(aim, type); } } }
@Override public void handleMessage(SoapMessage soapMessage) throws Fault { AssertionInfoMap aim = soapMessage.get(AssertionInfoMap.class); @SuppressWarnings("unchecked") final List<SecurityEvent> incomingSecurityEventList = (List<SecurityEvent>) soapMessage.get(SecurityEvent.class.getName() + ".in"); if (aim == null || incomingSecurityEventList == null) { return; } // First check for a SOAP Fault with no security header if we are the client // In this case don't blanket assert security policies if (MessageUtils.isRequestor(soapMessage) && incomingSecurityEventList.contains(WSSecurityEventConstants.NoSecurity)) { OperationSecurityEvent securityEvent = (OperationSecurityEvent) findEvent(WSSecurityEventConstants.Operation, incomingSecurityEventList); if (securityEvent != null && soapMessage.getVersion().getFault().equals(securityEvent.getOperation())) { LOG.warning("Request does not contain Security header, but it's a fault."); return; } } assertAllSecurityAssertions(aim); }
protected void processToken(SoapMessage message) { Header h = findSecurityHeader(message, false); if (h == null) { return; } boolean utWithCallbacks = MessageUtils.getContextualBoolean(message, SecurityConstants.VALIDATE_TOKEN, true); Element el = (Element) h.getObject(); Element child = DOMUtils.getFirstElement(el); while (child != null) { if (SPConstants.USERNAME_TOKEN.equals(child.getLocalName()) && WSConstants.WSSE_NS.equals(child.getNamespaceURI())) { try { Principal principal = null; Subject subject = null; if (utWithCallbacks) { final WSSecurityEngineResult result = validateToken(child, message); principal = (Principal) result.get(WSSecurityEngineResult.TAG_PRINCIPAL); subject = (Subject) result.get(WSSecurityEngineResult.TAG_SUBJECT); } else { boolean bspCompliant = isWsiBSPCompliant(message); principal = parseTokenAndCreatePrincipal(child, bspCompliant); WSS4JTokenConverter.convertToken(message, principal); } SecurityContext sc = message.get(SecurityContext.class); if (sc == null || sc.getUserPrincipal() == null) { if (subject != null && principal != null) { message.put(SecurityContext.class, createSecurityContext(principal, subject)); } else if (principal instanceof UsernameTokenPrincipal) { UsernameTokenPrincipal utPrincipal = (UsernameTokenPrincipal) principal; String nonce = null; if (utPrincipal.getNonce() != null) { nonce = Base64.encode(utPrincipal.getNonce()); } subject = createSubject( utPrincipal.getName(), utPrincipal.getPassword(), utPrincipal.isPasswordDigest(), nonce, utPrincipal.getCreatedTime()); message.put(SecurityContext.class, createSecurityContext(utPrincipal, subject)); } } if (principal instanceof UsernameTokenPrincipal) { storeResults((UsernameTokenPrincipal) principal, message); } } catch (WSSecurityException ex) { throw new Fault(ex); } catch (Base64DecodingException ex) { throw new Fault(ex); } } child = DOMUtils.getNextElement(child); } }
public UriInfoImpl(Message m, MultivaluedMap<String, String> templateParams) { this.message = m; this.templateParams = templateParams; if (m != null) { this.stack = m.get(OperationResourceInfoStack.class); this.caseInsensitiveQueries = MessageUtils.isTrue(m.getContextualProperty(CASE_INSENSITIVE_QUERIES)); } }
private String getAbsolutePathAsString() { String address = getBaseUri().toString(); if (MessageUtils.isRequestor(message)) { return address; } String path = doGetPath(false, false); if (path.startsWith("/") && address.endsWith("/")) { address = address.substring(0, address.length() - 1); } return address + path; }
/** * Check for NONE ReplyTo value in request-response MEP * * @param message the current message * @param maps the incoming MAPs */ private void checkReplyTo(Message message, AddressingProperties maps) { // if ReplyTo address is none then 202 response status is expected // However returning a fault is more appropriate for request-response MEP if (!message.getExchange().isOneWay() && !MessageUtils.isPartialResponse(message) && ContextUtils.isNoneAddress(maps.getReplyTo())) { String reason = MessageFormat.format( BUNDLE.getString("REPLYTO_NOT_SUPPORTED_MSG"), maps.getReplyTo().getAddress().getValue()); throw new SoapFault(reason, new QName(Names.WSA_NAMESPACE_NAME, Names.WSA_NONE_ADDRESS)); } }
/** @param message */ @Override public void handleMessage(SoapMessage message) throws Fault { long l = LOG.logStart(); final OutputStream os = message.getContent(OutputStream.class); boolean isRequestor = MessageUtils.isRequestor(message); if (os == null) { LOG.logWarn("Could not log message because it not contains OutputStream!", null); return; } // create store file File fStore; if (isRequestor) { MSHOutMail rq = SoapUtils.getMSHOutMail(message); fStore = EBMSLogUtils.getOutboundFileName(true, rq.getId(), null); } else { // get base from input log file String base = (String) message.getExchange().get(EBMSConstants.EBMS_CP_BASE_LOG_SOAP_MESSAGE_FILE); fStore = EBMSLogUtils.getOutboundFileName(false, null, base); } LOG.log("Out " + (isRequestor ? "request" : "response") + " stored to:" + fStore.getName()); message .getExchange() .put( EBMSConstants.EBMS_CP_BASE_LOG_SOAP_MESSAGE_FILE, EBMSLogUtils.getBaseFileName(fStore)); message.getExchange().put(EBMSConstants.EBMS_CP_OUT_LOG_SOAP_MESSAGE_FILE, fStore); // create FileOutputStream to log request FileOutputStream fos; try { fos = new FileOutputStream(fStore); } catch (FileNotFoundException ex) { String errmsg = "Could not log outbound message to file: '" + fStore.getAbsolutePath() + "'! "; LOG.logError(l, errmsg, ex); return; } // create CacheAndWriteOutputStream final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os); message.setContent(OutputStream.class, newOut); newOut.registerCallback(new LoggingCallback(fos, message, os, fStore)); LOG.logEnd(l); }
public static final void disableMTOMResponse(WebServiceContext wsContext) { MessageContext msgCtx = wsContext.getMessageContext(); WrappedMessageContext wmc = (WrappedMessageContext) msgCtx; Exchange ex = wmc.getWrappedMessage().getExchange(); Message out = ex.getOutMessage(); if (out != null) { int i = 0; for (; MessageUtils.isTrue(out.getContextualProperty(Message.MTOM_ENABLED)) && i < 10; i++) { out.setContextualProperty(Message.MTOM_ENABLED, false); log.debug( "###### disableMTOM! enabled:{}", out.getContextualProperty(Message.MTOM_ENABLED)); } if (i > 1) log.warn( "###### disable MTOM needs " + i + " tries! enabled:{}", out.getContextualProperty(Message.MTOM_ENABLED)); } log.debug("###### MTOM enabled? {}:", out.getContextualProperty(Message.MTOM_ENABLED)); }
private boolean checkBufferingMode(Message m, List<WriterInterceptor> writers, boolean firstTry) { if (!firstTry) { return false; } WriterInterceptor last = writers.get(writers.size() - 1); MessageBodyWriter<Object> w = ((WriterInterceptorMBW) last).getMBW(); Object outBuf = m.getContextualProperty(OUT_BUFFERING); boolean enabled = MessageUtils.isTrue(outBuf); boolean configurableProvider = w instanceof AbstractConfigurableProvider; if (!enabled && outBuf == null && configurableProvider) { enabled = ((AbstractConfigurableProvider) w).getEnableBuffering(); } if (enabled) { boolean streamingOn = configurableProvider ? ((AbstractConfigurableProvider) w).getEnableStreaming() : false; if (streamingOn) { m.setContent(XMLStreamWriter.class, new CachingXmlEventWriter()); } else { m.setContent(OutputStream.class, new CachedOutputStream()); } } return enabled; }
private void serializeMessage( ServerProviderFactory providerFactory, Message message, Response theResponse, OperationResourceInfo ori, boolean firstTry) { ResponseImpl response = (ResponseImpl) JAXRSUtils.copyResponseIfNeeded(theResponse); final Exchange exchange = message.getExchange(); boolean headResponse = response.getStatus() == 200 && firstTry && ori != null && HttpMethod.HEAD.equals(ori.getHttpMethod()); Object entity = response.getActualEntity(); if (headResponse && entity != null) { LOG.info(new org.apache.cxf.common.i18n.Message("HEAD_WITHOUT_ENTITY", BUNDLE).toString()); entity = null; } Method invoked = ori == null ? null : ori.getAnnotatedMethod() != null ? ori.getAnnotatedMethod() : ori.getMethodToInvoke(); Annotation[] annotations = null; Annotation[] staticAnns = ori != null ? ori.getOutAnnotations() : new Annotation[] {}; Annotation[] responseAnns = response.getEntityAnnotations(); if (responseAnns != null) { annotations = new Annotation[staticAnns.length + responseAnns.length]; System.arraycopy(staticAnns, 0, annotations, 0, staticAnns.length); System.arraycopy(responseAnns, 0, annotations, staticAnns.length, responseAnns.length); } else { annotations = staticAnns; } response.setStatus(getActualStatus(response.getStatus(), entity)); response.setEntity(entity, annotations); // Prepare the headers MultivaluedMap<String, Object> responseHeaders = prepareResponseHeaders(message, response, entity, firstTry); // Run the filters try { JAXRSUtils.runContainerResponseFilters(providerFactory, response, message, ori, invoked); } catch (Throwable ex) { handleWriteException(providerFactory, message, ex, firstTry); return; } // Write the entity entity = InjectionUtils.getEntity(response.getActualEntity()); setResponseStatus(message, getActualStatus(response.getStatus(), entity)); if (entity == null) { if (!headResponse) { responseHeaders.putSingle(HttpHeaders.CONTENT_LENGTH, "0"); if (MessageUtils.getContextualBoolean( message, "remove.content.type.for.empty.response", false)) { responseHeaders.remove(HttpHeaders.CONTENT_TYPE); message.remove(Message.CONTENT_TYPE); } } HttpUtils.convertHeaderValuesToString(responseHeaders, true); return; } Object ignoreWritersProp = exchange.get(JAXRSUtils.IGNORE_MESSAGE_WRITERS); boolean ignoreWriters = ignoreWritersProp == null ? false : Boolean.valueOf(ignoreWritersProp.toString()); if (ignoreWriters) { writeResponseToStream(message.getContent(OutputStream.class), entity); return; } MediaType responseMediaType = getResponseMediaType(responseHeaders.getFirst(HttpHeaders.CONTENT_TYPE)); Class<?> serviceCls = invoked != null ? ori.getClassResourceInfo().getServiceClass() : null; Class<?> targetType = InjectionUtils.getRawResponseClass(entity); Type genericType = InjectionUtils.getGenericResponseType( invoked, serviceCls, response.getActualEntity(), targetType, exchange); targetType = InjectionUtils.updateParamClassToTypeIfNeeded(targetType, genericType); annotations = response.getEntityAnnotations(); List<WriterInterceptor> writers = providerFactory.createMessageBodyWriterInterceptor( targetType, genericType, annotations, responseMediaType, message, ori == null ? null : ori.getNameBindings()); OutputStream outOriginal = message.getContent(OutputStream.class); if (writers == null || writers.isEmpty()) { writeResponseErrorMessage( message, outOriginal, "NO_MSG_WRITER", targetType, responseMediaType); return; } try { boolean checkWriters = false; if (responseMediaType.isWildcardSubtype()) { Produces pM = AnnotationUtils.getMethodAnnotation( ori == null ? null : ori.getAnnotatedMethod(), Produces.class); Produces pC = AnnotationUtils.getClassAnnotation(serviceCls, Produces.class); checkWriters = pM == null && pC == null; } responseMediaType = checkFinalContentType(responseMediaType, writers, checkWriters); } catch (Throwable ex) { handleWriteException(providerFactory, message, ex, firstTry); return; } String finalResponseContentType = JAXRSUtils.mediaTypeToString(responseMediaType); if (LOG.isLoggable(Level.FINE)) { LOG.fine("Response content type is: " + finalResponseContentType); } responseHeaders.putSingle(HttpHeaders.CONTENT_TYPE, finalResponseContentType); message.put(Message.CONTENT_TYPE, finalResponseContentType); boolean enabled = checkBufferingMode(message, writers, firstTry); try { try { JAXRSUtils.writeMessageBody( writers, entity, targetType, genericType, annotations, responseMediaType, responseHeaders, message); if (isResponseRedirected(message)) { return; } checkCachedStream(message, outOriginal, enabled); } finally { if (enabled) { OutputStream os = message.getContent(OutputStream.class); if (os != outOriginal && os instanceof CachedOutputStream) { os.close(); } message.setContent(OutputStream.class, outOriginal); message.put(XMLStreamWriter.class.getName(), null); } } } catch (Throwable ex) { logWriteError(firstTry, targetType, responseMediaType); handleWriteException(providerFactory, message, ex, firstTry); } }
/** * This method is called by {@link CxfConsumer} to populate a CXF response exchange from a Camel * exchange. */ public void populateCxfResponseFromExchange( Exchange camelExchange, org.apache.cxf.message.Exchange cxfExchange) { if (cxfExchange.isOneWay()) { return; } // create response context Map<String, Object> responseContext = new HashMap<String, Object>(); org.apache.camel.Message response; if (camelExchange.getPattern().isOutCapable()) { if (camelExchange.hasOut()) { response = camelExchange.getOut(); LOG.trace("Get the response from the out message"); } else { // Take the in message as a fall back response = camelExchange.getIn(); LOG.trace("Get the response from the in message as a fallback"); } } else { response = camelExchange.getIn(); LOG.trace("Get the response from the in message"); } // propagate response context Map<String, Object> camelHeaders = response.getHeaders(); extractInvocationContextFromCamel( camelExchange, camelHeaders, responseContext, Client.RESPONSE_CONTEXT); propagateHeadersFromCamelToCxf(camelExchange, camelHeaders, cxfExchange, responseContext); // create out message Endpoint ep = cxfExchange.get(Endpoint.class); Message outMessage = ep.getBinding().createMessage(); cxfExchange.setOutMessage(outMessage); DataFormat dataFormat = camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.class); // make sure the "requestor role" property does not get propagated as we do switch role responseContext.remove(Message.REQUESTOR_ROLE); outMessage.putAll(responseContext); // Do we still need to put the response context back like this outMessage.put(Client.RESPONSE_CONTEXT, responseContext); LOG.trace("Set out response context = {}", responseContext); // set body Object outBody = DefaultCxfBinding.getBodyFromCamel(response, dataFormat); if (outBody != null) { if (dataFormat == DataFormat.PAYLOAD) { CxfPayload<?> payload = (CxfPayload<?>) outBody; outMessage.setContent( List.class, getResponsePayloadList(cxfExchange, payload.getBodySources())); outMessage.put(Header.HEADER_LIST, payload.getHeaders()); } else { if (responseContext.get(Header.HEADER_LIST) != null) { outMessage.put(Header.HEADER_LIST, responseContext.get(Header.HEADER_LIST)); } MessageContentsList resList = null; // Create a new MessageContentsList to avoid OOM from the HolderOutInterceptor if (outBody instanceof List) { resList = new MessageContentsList((List<?>) outBody); } else if (outBody.getClass().isArray()) { resList = new MessageContentsList((Object[]) outBody); } else { resList = new MessageContentsList(outBody); } if (resList != null) { outMessage.setContent(List.class, resList); LOG.trace("Set Out CXF message content = {}", resList); } } } else if (!cxfExchange.isOneWay() && cxfExchange.getInMessage() != null && MessageUtils.isTrue( cxfExchange .getInMessage() .getContextualProperty("jaxws.provider.interpretNullAsOneway"))) { // treat this non-oneway call as oneway when the provider returns a null changeToOneway(cxfExchange); return; } // propagate attachments Set<Attachment> attachments = null; boolean isXop = Boolean.valueOf(camelExchange.getProperty(Message.MTOM_ENABLED, String.class)); for (Map.Entry<String, DataHandler> entry : camelExchange.getOut().getAttachments().entrySet()) { if (attachments == null) { attachments = new HashSet<Attachment>(); } AttachmentImpl attachment = new AttachmentImpl(entry.getKey(), entry.getValue()); attachment.setXOP(isXop); attachments.add(attachment); } if (attachments != null) { outMessage.setAttachments(attachments); } BindingOperationInfo boi = cxfExchange.get(BindingOperationInfo.class); if (boi != null) { cxfExchange.put(BindingMessageInfo.class, boi.getOutput()); } }
protected ResponseBuilder setResponseBuilder(Message outMessage, Exchange exchange) throws Exception { Response response = exchange.get(Response.class); if (response != null) { outMessage .getExchange() .getInMessage() .put(Message.PROTOCOL_HEADERS, response.getStringHeaders()); return JAXRSUtils.fromResponse(JAXRSUtils.copyResponseIfNeeded(response)); } Integer status = getResponseCode(exchange); ResponseBuilder currentResponseBuilder = JAXRSUtils.toResponseBuilder(status); Message responseMessage = exchange.getInMessage() != null ? exchange.getInMessage() : exchange.getInFaultMessage(); // if there is no response message, we just send the response back directly if (responseMessage == null) { return currentResponseBuilder; } Map<String, List<Object>> protocolHeaders = CastUtils.cast((Map<?, ?>) responseMessage.get(Message.PROTOCOL_HEADERS)); boolean splitHeaders = MessageUtils.isTrue(outMessage.getContextualProperty(HEADER_SPLIT_PROPERTY)); for (Map.Entry<String, List<Object>> entry : protocolHeaders.entrySet()) { if (null == entry.getKey()) { continue; } if (entry.getValue().size() > 0) { if (HttpUtils.isDateRelatedHeader(entry.getKey())) { currentResponseBuilder.header(entry.getKey(), entry.getValue().get(0)); continue; } for (Object valObject : entry.getValue()) { if (splitHeaders && valObject instanceof String) { String val = (String) valObject; String[] values; if (val == null || val.length() == 0) { values = new String[] {""}; } else if (val.charAt(0) == '"' && val.charAt(val.length() - 1) == '"') { // if the value starts with a quote and ends with a quote, we do a best // effort attempt to determine what the individual values are. values = parseQuotedHeaderValue(val); } else { boolean splitPossible = !(HttpHeaders.SET_COOKIE.equalsIgnoreCase(entry.getKey()) && val.toUpperCase().contains(HttpHeaders.EXPIRES.toUpperCase())); values = splitPossible ? val.split(",") : new String[] {val}; } for (String s : values) { String theValue = s.trim(); if (theValue.length() > 0) { currentResponseBuilder.header(entry.getKey(), theValue); } } } else { currentResponseBuilder.header(entry.getKey(), valObject); } } } } String ct = (String) responseMessage.get(Message.CONTENT_TYPE); if (ct != null) { currentResponseBuilder.type(ct); } InputStream mStream = responseMessage.getContent(InputStream.class); currentResponseBuilder.entity(mStream); return currentResponseBuilder; }
protected boolean responseStreamCanBeClosed(Message outMessage, Class<?> cls) { return cls != InputStream.class && MessageUtils.isTrue(outMessage.getContextualProperty("response.stream.auto.close")); }
@Override protected void writeParts( Message message, Exchange exchange, BindingOperationInfo operation, MessageContentsList objs, List<MessagePartInfo> parts) { // TODO Auto-generated method stub OutputStream out = message.getContent(OutputStream.class); XMLStreamWriter origXmlWriter = message.getContent(XMLStreamWriter.class); Service service = exchange.getService(); XMLStreamWriter xmlWriter = origXmlWriter; CachingXmlEventWriter cache = null; Object en = message.getContextualProperty(OUT_BUFFERING); boolean allowBuffer = true; boolean buffer = false; if (en != null) { buffer = Boolean.TRUE.equals(en) || "true".equals(en); allowBuffer = !(Boolean.FALSE.equals(en) || "false".equals(en)); } // need to cache the events in case validation fails or buffering is enabled if (buffer || (allowBuffer && shouldValidate(message) && !isRequestor(message))) { cache = new CachingXmlEventWriter(); try { cache.setNamespaceContext(origXmlWriter.getNamespaceContext()); } catch (XMLStreamException e) { // ignorable, will just get extra namespace decls } xmlWriter = cache; out = null; } if (out != null && writeToOutputStream(message, operation.getBinding(), service) && !MessageUtils.isTrue(message.getContextualProperty(DISABLE_OUTPUTSTREAM_OPTIMIZATION))) { if (xmlWriter != null) { try { xmlWriter.writeCharacters(""); xmlWriter.flush(); } catch (XMLStreamException e) { throw new Fault(e); } } DataWriter<OutputStream> osWriter = getDataWriter(message, service, OutputStream.class); for (MessagePartInfo part : parts) { if (objs.hasValue(part)) { Object o = objs.get(part); osWriter.write(o, part, out); } } } else { DataWriter<XMLStreamWriter> dataWriter = new CustomDataWriter(prismContext); for (MessagePartInfo part : parts) { if (objs.hasValue(part)) { Object o = objs.get(part); dataWriter.write(o, part, xmlWriter); } } } if (cache != null) { try { for (XMLEvent event : cache.getEvents()) { StaxUtils.writeEvent(event, origXmlWriter); } } catch (XMLStreamException e) { throw new Fault(e); } } }
private void doSignature( AbstractTokenWrapper wrapper, AbstractToken policyToken, SecurityToken tok, List<SecurePart> sigParts) throws WSSecurityException, SOAPException { // Action WSSSecurityProperties properties = getProperties(); WSSConstants.Action actionToPerform = WSSConstants.SIGNATURE; if (wrapper.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) { actionToPerform = WSSConstants.SIGNATURE_WITH_DERIVED_KEY; if (MessageUtils.isRequestor(message) && policyToken instanceof X509Token) { properties.setDerivedKeyTokenReference(WSSConstants.DerivedKeyTokenReference.EncryptedKey); } else { properties.setDerivedKeyTokenReference( WSSConstants.DerivedKeyTokenReference.DirectReference); } AlgorithmSuiteType algSuiteType = sbinding.getAlgorithmSuite().getAlgorithmSuiteType(); properties.setDerivedSignatureKeyLength(algSuiteType.getSignatureDerivedKeyLength() / 8); } if (policyToken.getVersion() == SPConstants.SPVersion.SP12) { properties.setUse200512Namespace(true); } List<WSSConstants.Action> actionList = properties.getActions(); // Add a Signature directly before Kerberos, otherwise just append it boolean actionAdded = false; for (int i = 0; i < actionList.size(); i++) { WSSConstants.Action action = actionList.get(i); if (action.equals(WSSConstants.KERBEROS_TOKEN)) { actionList.add(i, actionToPerform); actionAdded = true; break; } } if (!actionAdded) { actionList.add(actionToPerform); } properties.getSignatureSecureParts().addAll(sigParts); AbstractToken sigToken = wrapper.getToken(); if (sbinding.isProtectTokens() && sigToken instanceof X509Token && isRequestor()) { SecurePart securePart = new SecurePart(new QName(WSSConstants.NS_XMLENC, "EncryptedKey"), Modifier.Element); properties.addSignaturePart(securePart); } configureSignature(sigToken, false); if (policyToken instanceof X509Token) { properties.setIncludeSignatureToken(false); if (isRequestor()) { properties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_EncryptedKey); } else { properties.setSignatureKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_ENCRYPTED_KEY_SHA1_IDENTIFIER); if (wrapper.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) { properties.setDerivedKeyKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_ENCRYPTED_KEY_SHA1_IDENTIFIER); properties.setSignatureKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE); } } } else if (policyToken instanceof KerberosToken) { if (isRequestor()) { properties.setDerivedKeyKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE); } else { if (wrapper.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) { properties.setSignatureKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE); } else { properties.setSignatureKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_KERBEROS_SHA1_IDENTIFIER); } properties.setDerivedKeyKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_KERBEROS_SHA1_IDENTIFIER); } } else if (policyToken instanceof IssuedToken || policyToken instanceof SecurityContextToken || policyToken instanceof SecureConversationToken || policyToken instanceof SpnegoContextToken) { if (!isRequestor()) { properties.setIncludeSignatureToken(false); } else { properties.setIncludeSignatureToken(true); } properties.setDerivedKeyKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE); } if (sigToken.getDerivedKeys() == DerivedKeys.RequireDerivedKeys) { properties.setSignatureAlgorithm(sbinding.getAlgorithmSuite().getSymmetricSignature()); } }
/** * Asserts all Addressing assertions for the current message, regardless their nested Policies. * * @param message the current message */ private void assertAddressing( Message message, EndpointReferenceType replyTo, EndpointReferenceType faultTo) { AssertionInfoMap aim = message.get(AssertionInfoMap.class); if (null == aim) { return; } if (faultTo == null) { faultTo = replyTo; } boolean anonReply = ContextUtils.isGenericAddress(replyTo); boolean anonFault = ContextUtils.isGenericAddress(faultTo); boolean onlyAnonymous = anonReply && anonFault; boolean hasAnonymous = anonReply || anonFault; QName[] types = new QName[] { MetadataConstants.ADDRESSING_ASSERTION_QNAME, MetadataConstants.USING_ADDRESSING_2004_QNAME, MetadataConstants.USING_ADDRESSING_2005_QNAME, MetadataConstants.USING_ADDRESSING_2006_QNAME }; for (QName type : types) { assertAssertion(aim, type); if (type.equals(MetadataConstants.ADDRESSING_ASSERTION_QNAME)) { if (onlyAnonymous) { assertAssertion(aim, MetadataConstants.ANON_RESPONSES_ASSERTION_QNAME); } else if (!hasAnonymous) { assertAssertion(aim, MetadataConstants.NON_ANON_RESPONSES_ASSERTION_QNAME); } } else if (type.equals(MetadataConstants.ADDRESSING_ASSERTION_QNAME_0705)) { if (onlyAnonymous) { assertAssertion(aim, MetadataConstants.ANON_RESPONSES_ASSERTION_QNAME_0705); } else if (!hasAnonymous) { assertAssertion(aim, MetadataConstants.NON_ANON_RESPONSES_ASSERTION_QNAME_0705); } } } if (!MessageUtils.isRequestor(message) && !MessageUtils.isOutbound(message)) { // need to throw an appropriate fault for these Collection<AssertionInfo> aicNonAnon = aim.getAssertionInfo(MetadataConstants.NON_ANON_RESPONSES_ASSERTION_QNAME); Collection<AssertionInfo> aicNonAnon2 = aim.getAssertionInfo(MetadataConstants.NON_ANON_RESPONSES_ASSERTION_QNAME_0705); Collection<AssertionInfo> aicAnon = aim.getAssertionInfo(MetadataConstants.ANON_RESPONSES_ASSERTION_QNAME); Collection<AssertionInfo> aicAnon2 = aim.getAssertionInfo(MetadataConstants.ANON_RESPONSES_ASSERTION_QNAME_0705); boolean hasAnon = (aicAnon != null && !aicAnon.isEmpty()) || (aicAnon2 != null && !aicAnon2.isEmpty()); boolean hasNonAnon = (aicNonAnon != null && !aicNonAnon.isEmpty()) || (aicNonAnon2 != null && !aicNonAnon2.isEmpty()); if (hasAnonymous && hasNonAnon && !hasAnon) { message.put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT); if (isSOAP12(message)) { SoapFault soap12Fault = new SoapFault( "Found anonymous address but non-anonymous required", Soap12.getInstance().getSender()); soap12Fault.addSubCode( new QName(Names.WSA_NAMESPACE_NAME, "OnlyNonAnonymousAddressSupported")); throw soap12Fault; } throw new SoapFault( "Found anonymous address but non-anonymous required", new QName(Names.WSA_NAMESPACE_NAME, "OnlyNonAnonymousAddressSupported")); } else if (!onlyAnonymous && !hasNonAnon && hasAnon) { message.put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT); if (isSOAP12(message)) { SoapFault soap12Fault = new SoapFault( "Found non-anonymous address but only anonymous supported", Soap12.getInstance().getSender()); soap12Fault.addSubCode( new QName(Names.WSA_NAMESPACE_NAME, "OnlyAnonymousAddressSupported")); throw soap12Fault; } throw new SoapFault( "Found non-anonymous address but only anonymous supported", new QName(Names.WSA_NAMESPACE_NAME, "OnlyAnonymousAddressSupported")); } } }
// CHECKSTYLE:OFF - spec requires a bunch of params public W3CEndpointReference createW3CEndpointReference( String address, QName interfaceName, QName serviceName, QName portName, List<Element> metadata, String wsdlDocumentLocation, List<Element> referenceParameters, List<Element> elements, Map<QName, String> attributes) { // CHECKSTYLE:ON if (serviceName != null && portName != null && wsdlDocumentLocation != null && interfaceName == null) { Bus bus = BusFactory.getThreadDefaultBus(); WSDLManager wsdlManager = bus.getExtension(WSDLManager.class); try { Definition def = wsdlManager.getDefinition(wsdlDocumentLocation); interfaceName = def.getService(serviceName) .getPort(portName.getLocalPart()) .getBinding() .getPortType() .getQName(); } catch (Exception e) { // do nothing } } if (serviceName == null && portName == null && address == null) { throw new IllegalStateException( "Address in an EPR cannot be null, " + " when serviceName or portName is null"); } try { W3CDOMStreamWriter writer = new W3CDOMStreamWriter(); writer.setPrefix(JAXWSAConstants.WSA_PREFIX, JAXWSAConstants.NS_WSA); writer.writeStartElement( JAXWSAConstants.WSA_PREFIX, JAXWSAConstants.WSA_ERF_NAME, JAXWSAConstants.NS_WSA); writer.writeNamespace(JAXWSAConstants.WSA_PREFIX, JAXWSAConstants.NS_WSA); writer.writeStartElement( JAXWSAConstants.WSA_PREFIX, JAXWSAConstants.WSA_ADDRESS_NAME, JAXWSAConstants.NS_WSA); address = address == null ? "" : address; writer.writeCharacters(address); writer.writeEndElement(); if (referenceParameters != null) { writer.writeStartElement( JAXWSAConstants.WSA_PREFIX, JAXWSAConstants.WSA_REFERENCEPARAMETERS_NAME, JAXWSAConstants.NS_WSA); for (Element ele : referenceParameters) { StaxUtils.writeElement(ele, writer, true); } writer.writeEndElement(); } if (wsdlDocumentLocation != null || interfaceName != null || serviceName != null || (metadata != null && metadata.size() > 0)) { writer.writeStartElement( JAXWSAConstants.WSA_PREFIX, JAXWSAConstants.WSA_METADATA_NAME, JAXWSAConstants.NS_WSA); writer.writeNamespace(JAXWSAConstants.WSAW_PREFIX, JAXWSAConstants.NS_WSAW); writer.writeNamespace(JAXWSAConstants.WSAM_PREFIX, JAXWSAConstants.NS_WSAM); if (wsdlDocumentLocation != null) { boolean includeLocationOnly = false; org.apache.cxf.message.Message message = PhaseInterceptorChain.getCurrentMessage(); if (message != null) { includeLocationOnly = MessageUtils.isTrue( message.getContextualProperty("org.apache.cxf.wsa.metadata.wsdlLocationOnly")); } String attrubuteValue = serviceName != null && !includeLocationOnly ? serviceName.getNamespaceURI() + " " + wsdlDocumentLocation : wsdlDocumentLocation; writer.writeNamespace(JAXWSAConstants.WSDLI_PFX, JAXWSAConstants.NS_WSDLI); writer.writeAttribute( JAXWSAConstants.WSDLI_PFX, JAXWSAConstants.NS_WSDLI, JAXWSAConstants.WSDLI_WSDLLOCATION, attrubuteValue); } if (interfaceName != null) { writer.writeStartElement( JAXWSAConstants.WSAM_PREFIX, JAXWSAConstants.WSAM_INTERFACE_NAME, JAXWSAConstants.NS_WSAM); String portTypePrefix = interfaceName.getPrefix(); if (portTypePrefix == null || portTypePrefix.equals("")) { portTypePrefix = "ns1"; } writer.writeNamespace(portTypePrefix, interfaceName.getNamespaceURI()); writer.writeCharacters(portTypePrefix + ":" + interfaceName.getLocalPart()); writer.writeEndElement(); } String serviceNamePrefix = null; if (serviceName != null) { serviceNamePrefix = (serviceName.getPrefix() == null || serviceName.getPrefix().length() == 0) ? "ns2" : serviceName.getPrefix(); writer.writeStartElement( JAXWSAConstants.WSAM_PREFIX, JAXWSAConstants.WSAM_SERVICENAME_NAME, JAXWSAConstants.NS_WSAM); if (portName != null) { writer.writeAttribute(JAXWSAConstants.WSAM_ENDPOINT_NAME, portName.getLocalPart()); } writer.writeNamespace(serviceNamePrefix, serviceName.getNamespaceURI()); writer.writeCharacters(serviceNamePrefix + ":" + serviceName.getLocalPart()); writer.writeEndElement(); } if (wsdlDocumentLocation != null) { writer.writeStartElement( WSDLConstants.WSDL_PREFIX, WSDLConstants.QNAME_DEFINITIONS.getLocalPart(), WSDLConstants.NS_WSDL11); writer.writeNamespace(WSDLConstants.WSDL_PREFIX, WSDLConstants.NS_WSDL11); writer.writeStartElement( WSDLConstants.WSDL_PREFIX, WSDLConstants.QNAME_IMPORT.getLocalPart(), WSDLConstants.QNAME_IMPORT.getNamespaceURI()); if (serviceName != null) { writer.writeAttribute(WSDLConstants.ATTR_NAMESPACE, serviceName.getNamespaceURI()); } writer.writeAttribute(WSDLConstants.ATTR_LOCATION, wsdlDocumentLocation); writer.writeEndElement(); writer.writeEndElement(); } if (metadata != null) { for (Element e : metadata) { StaxUtils.writeElement(e, writer, true); } } writer.writeEndElement(); } if (elements != null) { for (Element e : elements) { StaxUtils.writeElement(e, writer, true); } } writer.writeEndElement(); writer.flush(); Unmarshaller unmarshaller = getJAXBContext().createUnmarshaller(); return (W3CEndpointReference) unmarshaller.unmarshal(writer.getDocument()); } catch (Exception e) { throw new WebServiceException( new Message("ERROR_UNMARSHAL_ENDPOINTREFERENCE", LOG).toString(), e); } }
// Some CXF interceptors such as FIStaxOutInterceptor will indirectly initiate // an early copying of response code and headers into the HttpServletResponse // TODO : Pushing the filter processing and copying response headers into say // PRE-LOGICAl and PREPARE_SEND interceptors will most likely be a good thing // however JAX-RS MessageBodyWriters are also allowed to add response headers // which is reason why a MultipartMap parameter in MessageBodyWriter.writeTo // method is modifiable. Thus we do need to know if the initial copy has already // occurred: for now we will just use to ensure the correct status is set private boolean isResponseHeadersCopied(Message message) { return MessageUtils.isTrue(message.get(AbstractHTTPDestination.RESPONSE_HEADERS_COPIED)); }
protected void handle(Message msg) { if (MessageUtils.isRequestor(msg)) { LOG.fine("Is a requestor."); return; } Exchange exchange = msg.getExchange(); assert null != exchange; BindingOperationInfo boi = exchange.get(BindingOperationInfo.class); if (null == boi) { LOG.fine("No binding operation info."); return; } Endpoint e = exchange.get(Endpoint.class); if (null == e) { LOG.fine("No endpoint."); return; } EndpointInfo ei = e.getEndpointInfo(); Bus bus = exchange.get(Bus.class); PolicyEngine pe = bus.getExtension(PolicyEngine.class); if (null == pe) { return; } Destination destination = exchange.getDestination(); Exception ex = exchange.get(Exception.class); List<Interceptor<? extends Message>> faultInterceptors = new ArrayList<Interceptor<? extends Message>>(); Collection<Assertion> assertions = new ArrayList<Assertion>(); // 1. Check overridden policy Policy p = (Policy) msg.getContextualProperty(PolicyConstants.POLICY_OVERRIDE); if (p != null) { EndpointPolicyImpl endpi = new EndpointPolicyImpl(p); EffectivePolicyImpl effectivePolicy = new EffectivePolicyImpl(); effectivePolicy.initialise(endpi, (PolicyEngineImpl) pe, false, true); PolicyUtils.logPolicy( LOG, Level.FINEST, "Using effective policy: ", effectivePolicy.getPolicy()); faultInterceptors.addAll(effectivePolicy.getInterceptors()); assertions.addAll(effectivePolicy.getChosenAlternative()); } else { // 2. Process effective server policy BindingFaultInfo bfi = getBindingFaultInfo(msg, ex, boi); if (bfi == null && msg.get(FaultMode.class) != FaultMode.UNCHECKED_APPLICATION_FAULT && msg.get(FaultMode.class) != FaultMode.CHECKED_APPLICATION_FAULT) { return; } EffectivePolicy effectivePolicy = pe.getEffectiveServerFaultPolicy(ei, boi, bfi, destination); if (effectivePolicy != null) { faultInterceptors.addAll(effectivePolicy.getInterceptors()); assertions.addAll(effectivePolicy.getChosenAlternative()); } } // add interceptors into message chain for (Interceptor<? extends Message> oi : faultInterceptors) { msg.getInterceptorChain().add(oi); LOG.log(Level.FINE, "Added interceptor of type {0}", oi.getClass().getSimpleName()); } // insert assertions of the chosen alternative into the message if (null != assertions && !assertions.isEmpty()) { msg.put(AssertionInfoMap.class, new AssertionInfoMap(assertions)); } }
private void doResend(SoapMessage message) { try { // initialize copied interceptor chain for message PhaseInterceptorChain retransmitChain = manager.getRetransmitChain(message); ProtocolVariation protocol = RMContextUtils.getProtocolVariation(message); Endpoint endpoint = manager.getReliableEndpoint(message).getEndpoint(protocol); PhaseChainCache cache = new PhaseChainCache(); boolean after = true; if (retransmitChain == null) { // no saved retransmit chain, so construct one from scratch (won't work for WS-Security on // server, so // need to fix) retransmitChain = buildRetransmitChain(endpoint, cache); after = false; } message.setInterceptorChain(retransmitChain); // clear flag for SOAP out interceptor so envelope will be written message.remove(SoapOutInterceptor.WROTE_ENVELOPE_START); // discard all saved content Set<Class<?>> formats = message.getContentFormats(); List<CachedOutputStreamCallback> callbacks = null; for (Class<?> clas : formats) { Object content = message.getContent(clas); if (content != null) { LOG.info( "Removing " + clas.getName() + " content of actual type " + content.getClass().getName()); message.removeContent(clas); if (clas == OutputStream.class && content instanceof WriteOnCloseOutputStream) { callbacks = ((WriteOnCloseOutputStream) content).getCallbacks(); } } } // read SOAP headers from saved input stream RewindableInputStream is = (RewindableInputStream) message.get(RMMessageConstants.SAVED_CONTENT); is.rewind(); XMLStreamReader reader = StaxUtils.createXMLStreamReader(is, "UTF-8"); message.getHeaders().clear(); if (reader.getEventType() != XMLStreamConstants.START_ELEMENT && reader.nextTag() != XMLStreamConstants.START_ELEMENT) { throw new IllegalStateException("No document found"); } readHeaders(reader, message); int event; while ((event = reader.nextTag()) != XMLStreamConstants.START_ELEMENT) { if (event == XMLStreamConstants.END_ELEMENT) { throw new IllegalStateException("No body content present"); } } // set message addressing properties AddressingProperties maps = new MAPCodec().unmarshalMAPs(message); RMContextUtils.storeMAPs(maps, message, true, MessageUtils.isRequestor(message)); AttributedURIType to = null; if (null != maps) { to = maps.getTo(); } if (null == to) { LOG.log(Level.SEVERE, "NO_ADDRESS_FOR_RESEND_MSG"); return; } if (RMUtils.getAddressingConstants().getAnonymousURI().equals(to.getValue())) { LOG.log(Level.FINE, "Cannot resend to anonymous target"); return; } // initialize conduit for new message Conduit c = message.getExchange().getConduit(message); if (c == null) { c = buildConduit(message, endpoint, to); } c.prepare(message); // replace standard message marshaling with copy from saved stream ListIterator<Interceptor<? extends Message>> iterator = retransmitChain.getIterator(); while (iterator.hasNext()) { Interceptor<? extends Message> incept = iterator.next(); // remove JAX-WS interceptors which handle message modes and such if (incept.getClass().getName().startsWith("org.apache.cxf.jaxws.interceptors")) { retransmitChain.remove(incept); } else if (incept instanceof PhaseInterceptor && (((PhaseInterceptor<?>) incept).getPhase() == Phase.MARSHAL)) { // remove any interceptors from the marshal phase retransmitChain.remove(incept); } } retransmitChain.add(new CopyOutInterceptor(reader)); // restore callbacks on output stream if (callbacks != null) { OutputStream os = message.getContent(OutputStream.class); if (os != null) { WriteOnCloseOutputStream woc; if (os instanceof WriteOnCloseOutputStream) { woc = (WriteOnCloseOutputStream) os; } else { woc = new WriteOnCloseOutputStream(os); message.setContent(OutputStream.class, woc); } for (CachedOutputStreamCallback cb : callbacks) { woc.registerCallback(cb); } } } // send the message message.put(RMMessageConstants.RM_RETRANSMISSION, Boolean.TRUE); if (after) { retransmitChain.doInterceptStartingAfter(message, RMCaptureOutInterceptor.class.getName()); } else { retransmitChain.doIntercept(message); } if (LOG.isLoggable(Level.INFO)) { RMProperties rmps = RMContextUtils.retrieveRMProperties(message, true); SequenceType seq = rmps.getSequence(); LOG.log( Level.INFO, "Retransmitted message " + seq.getMessageNumber() + " in sequence " + seq.getIdentifier().getValue()); rmps = new RMProperties(); } } catch (Exception ex) { LOG.log(Level.SEVERE, "RESEND_FAILED_MSG", ex); } }
/** * Validate incoming MAPs * * @param maps the incoming MAPs * @param message the current message * @return true if incoming MAPs are valid * @pre inbound message, not requestor */ private boolean validateIncomingMAPs(AddressingProperties maps, Message message) { boolean valid = true; if (maps != null) { // WSAB spec, section 4.2 validation (SOAPAction must match action String sa = SoapActionInInterceptor.getSoapAction(message); String s1 = this.getActionUri(message, false); if (maps.getAction() == null || maps.getAction().getValue() == null) { String reason = BUNDLE.getString("MISSING_ACTION_MESSAGE"); ContextUtils.storeMAPFaultName(Names.HEADER_REQUIRED_NAME, message); ContextUtils.storeMAPFaultReason(reason, message); valid = false; } if (!StringUtils.isEmpty(sa) && valid && !MessageUtils.isTrue(message.get(MAPAggregator.ACTION_VERIFIED))) { if (sa.startsWith("\"")) { sa = sa.substring(1, sa.lastIndexOf('"')); } String action = maps.getAction() == null ? "" : maps.getAction().getValue(); if (!StringUtils.isEmpty(sa) && !sa.equals(action)) { // don't match, must send fault back.... String reason = BUNDLE.getString("INVALID_ADDRESSING_PROPERTY_MESSAGE"); ContextUtils.storeMAPFaultName(Names.ACTION_MISMATCH_NAME, message); ContextUtils.storeMAPFaultReason(reason, message); valid = false; } else if (!StringUtils.isEmpty(s1) && !action.equals(s1) && !action.equals(s1 + "Request") && !s1.equals(action + "Request")) { // if java first, it's likely to have "Request", if wsdl first, // it will depend if the wsdl:input has a name or not. Thus, we'll // check both plain and with the "Request" trailer // doesn't match what's in the wsdl/annotations String reason = BundleUtils.getFormattedString(BUNDLE, "ACTION_NOT_SUPPORTED_MSG", action); ContextUtils.storeMAPFaultName(Names.ACTION_NOT_SUPPORTED_NAME, message); ContextUtils.storeMAPFaultReason(reason, message); valid = false; } } AttributedURIType messageID = maps.getMessageID(); if (!message.getExchange().isOneWay() && (messageID == null || messageID.getValue() == null) && valid) { String reason = BUNDLE.getString("MISSING_ACTION_MESSAGE"); ContextUtils.storeMAPFaultName(Names.HEADER_REQUIRED_NAME, message); ContextUtils.storeMAPFaultReason(reason, message); valid = false; } // Always cache message IDs, even when the message is not valid for some // other reason. if (!allowDuplicates && messageID != null && messageID.getValue() != null && !messageIdCache.checkUniquenessAndCacheId(messageID.getValue())) { LOG.log(Level.WARNING, "DUPLICATE_MESSAGE_ID_MSG", messageID.getValue()); // Only throw the fault if something else has not already marked the // message as invalid. if (valid) { String reason = BUNDLE.getString("DUPLICATE_MESSAGE_ID_MSG"); String l7dReason = MessageFormat.format(reason, messageID.getValue()); ContextUtils.storeMAPFaultName(Names.DUPLICATE_MESSAGE_ID_NAME, message); ContextUtils.storeMAPFaultReason(l7dReason, message); } valid = false; } } else if (usingAddressingAdvisory) { String reason = BUNDLE.getString("MISSING_ACTION_MESSAGE"); ContextUtils.storeMAPFaultName(Names.HEADER_REQUIRED_NAME, message); ContextUtils.storeMAPFaultReason(reason, message); valid = false; } if (Names.INVALID_CARDINALITY_NAME.equals(ContextUtils.retrieveMAPFaultName(message))) { valid = false; } return valid; }
private void doEncryptBeforeSign() { try { AbstractTokenWrapper encryptionWrapper = getEncryptionToken(); assertTokenWrapper(encryptionWrapper); AbstractToken encryptionToken = encryptionWrapper.getToken(); String tokenId = null; SecurityToken tok = null; if (encryptionToken instanceof KerberosToken) { tok = getSecurityToken(); if (MessageUtils.isRequestor(message)) { addKerberosToken((KerberosToken) encryptionToken, false, true, true); } } else if (encryptionToken instanceof IssuedToken) { tok = getSecurityToken(); addIssuedToken((IssuedToken) encryptionToken, tok, false, true); if (tok == null && !isRequestor()) { org.apache.xml.security.stax.securityToken.SecurityToken securityToken = findInboundSecurityToken(WSSecurityEventConstants.SAML_TOKEN); tokenId = WSS4JUtils.parseAndStoreStreamingSecurityToken(securityToken, message); } } else if (encryptionToken instanceof SecureConversationToken || encryptionToken instanceof SecurityContextToken || encryptionToken instanceof SpnegoContextToken) { tok = getSecurityToken(); if (tok != null && isRequestor()) { WSSSecurityProperties properties = getProperties(); WSSConstants.Action actionToPerform = WSSConstants.CUSTOM_TOKEN; properties.addAction(actionToPerform); } else if (tok == null && !isRequestor()) { org.apache.xml.security.stax.securityToken.SecurityToken securityToken = findInboundSecurityToken(WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN); tokenId = WSS4JUtils.parseAndStoreStreamingSecurityToken(securityToken, message); } } else if (encryptionToken instanceof X509Token) { if (isRequestor()) { tokenId = setupEncryptedKey(encryptionWrapper, encryptionToken); } else { org.apache.xml.security.stax.securityToken.SecurityToken securityToken = findEncryptedKeyToken(); tokenId = WSS4JUtils.parseAndStoreStreamingSecurityToken(securityToken, message); } } else if (encryptionToken instanceof UsernameToken) { unassertPolicy(sbinding, "UsernameTokens not supported with Symmetric binding"); return; } assertToken(encryptionToken); if (tok == null) { tokenId = XMLUtils.getIDFromReference(tokenId); // Get hold of the token from the token storage tok = TokenStoreUtils.getTokenStore(message).getToken(tokenId); } // Store key if (!(MessageUtils.isRequestor(message) && encryptionToken instanceof KerberosToken)) { storeSecurityToken(encryptionToken, tok); } List<SecurePart> encrParts = null; List<SecurePart> sigParts = null; try { encrParts = getEncryptedParts(); // Signed parts are determined before encryption because encrypted signed headers // will not be included otherwise sigParts = getSignedParts(); } catch (SOAPException ex) { throw new Fault(ex); } addSupportingTokens(); if (encryptionToken != null && encrParts.size() > 0) { if (isRequestor()) { encrParts.addAll(encryptedTokensList); } // Check for signature protection if (sbinding.isEncryptSignature()) { SecurePart part = new SecurePart(new QName(WSSConstants.NS_DSIG, "Signature"), Modifier.Element); encrParts.add(part); if (signatureConfirmationAdded) { part = new SecurePart(WSSConstants.TAG_WSSE11_SIG_CONF, Modifier.Element); encrParts.add(part); } assertPolicy( new QName(sbinding.getName().getNamespaceURI(), SPConstants.ENCRYPT_SIGNATURE)); } doEncryption(encryptionWrapper, encrParts, true); } if (timestampAdded) { SecurePart part = new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), Modifier.Element); sigParts.add(part); } sigParts.addAll(this.getSignedParts()); if (sigParts.size() > 0) { AbstractTokenWrapper sigAbstractTokenWrapper = getSignatureToken(); if (sigAbstractTokenWrapper != null) { AbstractToken sigToken = sigAbstractTokenWrapper.getToken(); if (isRequestor()) { doSignature(sigAbstractTokenWrapper, sigToken, tok, sigParts); } else { addSignatureConfirmation(sigParts); doSignature(sigAbstractTokenWrapper, sigToken, tok, sigParts); } } } removeSignatureIfSignedSAML(); enforceEncryptBeforeSigningWithSignedSAML(); prependSignatureToSC(); putCustomTokenAfterSignature(); } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { throw new Fault(ex); } }
private void doSignBeforeEncrypt() { AbstractTokenWrapper sigAbstractTokenWrapper = getSignatureToken(); assertTokenWrapper(sigAbstractTokenWrapper); AbstractToken sigToken = sigAbstractTokenWrapper.getToken(); String sigTokId = null; try { SecurityToken sigTok = null; if (sigToken != null) { if (sigToken instanceof KerberosToken) { sigTok = getSecurityToken(); if (isRequestor()) { addKerberosToken((KerberosToken) sigToken, false, true, true); } } else if (sigToken instanceof IssuedToken) { sigTok = getSecurityToken(); addIssuedToken((IssuedToken) sigToken, sigTok, false, true); if (sigTok == null && !isRequestor()) { org.apache.xml.security.stax.securityToken.SecurityToken securityToken = findInboundSecurityToken(WSSecurityEventConstants.SAML_TOKEN); sigTokId = WSS4JUtils.parseAndStoreStreamingSecurityToken(securityToken, message); } } else if (sigToken instanceof SecureConversationToken || sigToken instanceof SecurityContextToken || sigToken instanceof SpnegoContextToken) { sigTok = getSecurityToken(); if (sigTok != null && isRequestor()) { WSSSecurityProperties properties = getProperties(); WSSConstants.Action actionToPerform = WSSConstants.CUSTOM_TOKEN; properties.addAction(actionToPerform); } else if (sigTok == null && !isRequestor()) { org.apache.xml.security.stax.securityToken.SecurityToken securityToken = findInboundSecurityToken(WSSecurityEventConstants.SECURITY_CONTEXT_TOKEN); sigTokId = WSS4JUtils.parseAndStoreStreamingSecurityToken(securityToken, message); } } else if (sigToken instanceof X509Token) { if (isRequestor()) { sigTokId = setupEncryptedKey(sigAbstractTokenWrapper, sigToken); } else { org.apache.xml.security.stax.securityToken.SecurityToken securityToken = findEncryptedKeyToken(); sigTokId = WSS4JUtils.parseAndStoreStreamingSecurityToken(securityToken, message); } } else if (sigToken instanceof UsernameToken) { unassertPolicy(sbinding, "UsernameTokens not supported with Symmetric binding"); return; } assertToken(sigToken); } else { unassertPolicy(sbinding, "No signature token"); return; } if (sigTok == null && StringUtils.isEmpty(sigTokId)) { unassertPolicy(sigAbstractTokenWrapper, "No signature token id"); return; } if (sigTok == null) { sigTok = TokenStoreUtils.getTokenStore(message).getToken(sigTokId); } // Store key if (!(MessageUtils.isRequestor(message) && sigToken instanceof KerberosToken)) { storeSecurityToken(sigToken, sigTok); } // Add timestamp List<SecurePart> sigs = new ArrayList<>(); if (timestampAdded) { SecurePart part = new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), Modifier.Element); sigs.add(part); } sigs.addAll(this.getSignedParts()); if (!isRequestor()) { addSignatureConfirmation(sigs); } if (!sigs.isEmpty()) { doSignature(sigAbstractTokenWrapper, sigToken, sigTok, sigs); } addSupportingTokens(); removeSignatureIfSignedSAML(); prependSignatureToSC(); // Encryption List<SecurePart> enc = getEncryptedParts(); // Check for signature protection if (sbinding.isEncryptSignature()) { SecurePart part = new SecurePart(new QName(WSSConstants.NS_DSIG, "Signature"), Modifier.Element); enc.add(part); if (signatureConfirmationAdded) { part = new SecurePart(WSSConstants.TAG_WSSE11_SIG_CONF, Modifier.Element); enc.add(part); } assertPolicy( new QName(sbinding.getName().getNamespaceURI(), SPConstants.ENCRYPT_SIGNATURE)); } // Do encryption if (isRequestor()) { enc.addAll(encryptedTokensList); } AbstractTokenWrapper encrAbstractTokenWrapper = getEncryptionToken(); doEncryption(encrAbstractTokenWrapper, enc, false); putCustomTokenAfterSignature(); } catch (Exception e) { throw new Fault(e); } }
private void doEncryption( AbstractTokenWrapper recToken, List<SecurePart> encrParts, boolean externalRef) throws SOAPException { // Do encryption if (recToken != null && recToken.getToken() != null) { AbstractToken encrToken = recToken.getToken(); AlgorithmSuite algorithmSuite = sbinding.getAlgorithmSuite(); // Action WSSSecurityProperties properties = getProperties(); WSSConstants.Action actionToPerform = WSSConstants.ENCRYPT; if (recToken.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) { actionToPerform = WSSConstants.ENCRYPT_WITH_DERIVED_KEY; if (MessageUtils.isRequestor(message) && recToken.getToken() instanceof X509Token) { properties.setDerivedKeyTokenReference( WSSConstants.DerivedKeyTokenReference.EncryptedKey); } else { properties.setDerivedKeyTokenReference( WSSConstants.DerivedKeyTokenReference.DirectReference); } AlgorithmSuiteType algSuiteType = sbinding.getAlgorithmSuite().getAlgorithmSuiteType(); properties.setDerivedEncryptionKeyLength(algSuiteType.getEncryptionDerivedKeyLength() / 8); } if (recToken.getVersion() == SPConstants.SPVersion.SP12) { properties.setUse200512Namespace(true); } properties.getEncryptionSecureParts().addAll(encrParts); properties.addAction(actionToPerform); if (isRequestor()) { properties.setEncryptionKeyIdentifier(getKeyIdentifierType(encrToken)); properties.setDerivedKeyKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE); } else if (recToken.getToken() instanceof KerberosToken && !isRequestor()) { properties.setEncryptionKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_KERBEROS_SHA1_IDENTIFIER); properties.setDerivedKeyKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_KERBEROS_SHA1_IDENTIFIER); if (recToken.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) { properties.setEncryptionKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE); } } else if ((recToken.getToken() instanceof IssuedToken || recToken.getToken() instanceof SecureConversationToken || recToken.getToken() instanceof SpnegoContextToken) && !isRequestor()) { properties.setEncryptionKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE); } else { properties.setEncryptionKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_ENCRYPTED_KEY_SHA1_IDENTIFIER); if (recToken.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) { properties.setDerivedKeyKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_ENCRYPTED_KEY_SHA1_IDENTIFIER); properties.setEncryptionKeyIdentifier( WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE); properties.setEncryptSymmetricEncryptionKey(false); } } // Find out do we also need to include the token as per the Inclusion requirement WSSecurityTokenConstants.KeyIdentifier keyIdentifier = properties.getEncryptionKeyIdentifier(); if (encrToken instanceof X509Token && isTokenRequired(encrToken.getIncludeTokenType()) && (WSSecurityTokenConstants.KeyIdentifier_IssuerSerial.equals(keyIdentifier) || WSSecurityTokenConstants.KEYIDENTIFIER_THUMBPRINT_IDENTIFIER.equals(keyIdentifier) || WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE.equals( keyIdentifier))) { properties.setIncludeEncryptionToken(true); } else { properties.setIncludeEncryptionToken(false); } properties.setEncryptionKeyTransportAlgorithm( algorithmSuite.getAlgorithmSuiteType().getAsymmetricKeyWrap()); properties.setEncryptionSymAlgorithm(algorithmSuite.getAlgorithmSuiteType().getEncryption()); String encUser = (String) SecurityUtils.getSecurityPropertyValue(SecurityConstants.ENCRYPT_USERNAME, message); if (encUser == null) { encUser = (String) SecurityUtils.getSecurityPropertyValue(SecurityConstants.USERNAME, message); } if (encUser != null && properties.getEncryptionUser() == null) { properties.setEncryptionUser(encUser); } if (ConfigurationConstants.USE_REQ_SIG_CERT.equals(encUser)) { properties.setUseReqSigCertForEncryption(true); } if (encrToken instanceof KerberosToken || encrToken instanceof IssuedToken || encrToken instanceof SpnegoContextToken || encrToken instanceof SecurityContextToken || encrToken instanceof SecureConversationToken) { properties.setEncryptSymmetricEncryptionKey(false); } } }
/** * Mediate message flow. * * @param message the current message * @param isFault true if a fault is being mediated * @return true if processing should continue on dispatch path */ protected boolean mediate(Message message, boolean isFault) { boolean continueProcessing = true; if (ContextUtils.isOutbound(message)) { if (usingAddressing(message)) { // request/response MAPs must be aggregated aggregate(message, isFault); } AddressingProperties theMaps = ContextUtils.retrieveMAPs(message, false, ContextUtils.isOutbound(message)); if (null != theMaps) { if (ContextUtils.isRequestor(message)) { assertAddressing(message, theMaps.getReplyTo(), theMaps.getFaultTo()); } else { checkReplyTo(message, theMaps); } } } else if (!ContextUtils.isRequestor(message)) { // responder validates incoming MAPs AddressingProperties maps = getMAPs(message, false, false); // check responses if (maps != null) { checkAddressingResponses(maps.getReplyTo(), maps.getFaultTo()); assertAddressing(message, maps.getReplyTo(), maps.getFaultTo()); } boolean isOneway = message.getExchange().isOneWay(); if (null == maps && !addressingRequired) { return false; } continueProcessing = validateIncomingMAPs(maps, message); if (maps != null) { AddressingProperties theMaps = ContextUtils.retrieveMAPs(message, false, ContextUtils.isOutbound(message)); if (null != theMaps) { assertAddressing(message, theMaps.getReplyTo(), theMaps.getFaultTo()); } if (isOneway || !ContextUtils.isGenericAddress(maps.getReplyTo())) { InternalContextUtils.rebaseResponse(maps.getReplyTo(), maps, message); } if (!isOneway) { if (ContextUtils.isNoneAddress(maps.getReplyTo())) { LOG.warning("Detected NONE value in ReplyTo WSA header for request-respone MEP"); } else { // ensure the inbound MAPs are available in both the full & fault // response messages (used to determine relatesTo etc.) ContextUtils.propogateReceivedMAPs(maps, message.getExchange()); } } } if (continueProcessing) { // any faults thrown from here on can be correlated with this message message.put(FaultMode.class, FaultMode.LOGICAL_RUNTIME_FAULT); } else { // validation failure => dispatch is aborted, response MAPs // must be aggregated // isFault = true; // aggregate(message, isFault); if (isSOAP12(message)) { SoapFault soap12Fault = new SoapFault( ContextUtils.retrieveMAPFaultReason(message), Soap12.getInstance().getSender()); soap12Fault.setSubCode( new QName(Names.WSA_NAMESPACE_NAME, ContextUtils.retrieveMAPFaultName(message))); throw soap12Fault; } throw new SoapFault( ContextUtils.retrieveMAPFaultReason(message), new QName(Names.WSA_NAMESPACE_NAME, ContextUtils.retrieveMAPFaultName(message))); } } else { AddressingProperties theMaps = ContextUtils.retrieveMAPs(message, false, ContextUtils.isOutbound(message)); if (null != theMaps) { assertAddressing(message, theMaps.getReplyTo(), theMaps.getFaultTo()); } // If the wsa policy is enabled , but the client sets the // WSAddressingFeature.isAddressingRequired to false , we need to assert all WSA assertion to // true if (!ContextUtils.isOutbound(message) && ContextUtils.isRequestor(message) && getWSAddressingFeature(message) != null && !getWSAddressingFeature(message).isAddressingRequired()) { assertAddressing(message); } // CXF-3060 :If wsa policy is not enforced, AddressingProperties map is null and // AddressingFeature.isRequired, requestor checks inbound message and throw exception if (null == theMaps && !ContextUtils.isOutbound(message) && ContextUtils.isRequestor(message) && getWSAddressingFeature(message) != null && getWSAddressingFeature(message).isAddressingRequired()) { boolean missingWsaHeader = false; AssertionInfoMap aim = message.get(AssertionInfoMap.class); if (aim == null || aim.size() == 0) { missingWsaHeader = true; } if (aim != null && aim.size() > 0) { missingWsaHeader = true; QName[] types = new QName[] { MetadataConstants.ADDRESSING_ASSERTION_QNAME, MetadataConstants.USING_ADDRESSING_2004_QNAME, MetadataConstants.USING_ADDRESSING_2005_QNAME, MetadataConstants.USING_ADDRESSING_2006_QNAME }; for (QName type : types) { for (AssertionInfo assertInfo : aim.getAssertionInfo(type)) { if (assertInfo.isAsserted()) { missingWsaHeader = false; } } } } if (missingWsaHeader) { throw new SoapFault( "MISSING_ACTION_MESSAGE", BUNDLE, new QName(Names.WSA_NAMESPACE_NAME, Names.HEADER_REQUIRED_NAME)); } } if (MessageUtils.isPartialResponse(message) && message.getExchange().getOutMessage() != null) { // marked as a partial response, let's see if it really is MessageInfo min = message.get(MessageInfo.class); MessageInfo mout = message.getExchange().getOutMessage().get(MessageInfo.class); if (min != null && mout != null && min.getOperation() == mout.getOperation() && message.getContent(List.class) != null) { // the in and out messages are on the same operation // and we were able to get a response for it. message.remove(Message.PARTIAL_RESPONSE_MESSAGE); } } } return continueProcessing; }
protected URI calculateNewRequestURI(Map<String, Object> reqContext) { URI newBaseURI = URI.create(reqContext.get(Message.ENDPOINT_ADDRESS).toString()); URI requestURI = URI.create(reqContext.get(Message.REQUEST_URI).toString()); return calculateNewRequestURI( newBaseURI, requestURI, MessageUtils.isTrue(reqContext.get(PROXY_PROPERTY))); }