@Override public void handleMessage(SoapMessage msg) throws Fault { Endpoint ep = msg.getExchange().get(Endpoint.class); sdc.set(ep.getSecurityDomainContext()); try { SecurityToken token = msg.get(SecurityToken.class); SecurityContext context = msg.get(SecurityContext.class); if (token == null || context == null || context.getUserPrincipal() == null) { super.handleMessage(msg); return; } UsernameToken ut = (UsernameToken) token; Subject subject = createSubject( ut.getName(), ut.getPassword(), ut.isHashed(), ut.getNonce(), ut.getCreatedTime()); SecurityContext sc = doCreateSecurityContext(context.getUserPrincipal(), subject); msg.put(SecurityContext.class, sc); } finally { if (sdc != null) { sdc.remove(); } } }
@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); } }
@Override public void handleMessage(SoapMessage message) throws Fault { if (message.getVersion() instanceof Soap11) { Map<String, List<String>> headers = CastUtils.cast((Map) message.get(Message.PROTOCOL_HEADERS)); headers.remove("SOAPAction"); } }
private SoapMessage coachMessage(String policyName) throws IOException, ParserConfigurationException, SAXException { Policy policy = policyBuilder.getPolicy(this.getResourceAsStream(policyName)); AssertionInfoMap aim = new AssertionInfoMap(policy); SoapMessage message = control.createMock(SoapMessage.class); EasyMock.expect(message.get(Message.REQUESTOR_ROLE)).andReturn(Boolean.TRUE); EasyMock.expect(message.get(AssertionInfoMap.class)).andReturn(aim); return message; }
protected UsernameToken assertTokens(SoapMessage message) { AssertionInfoMap aim = message.get(AssertionInfoMap.class); assertPolicy(aim, SPConstants.USERNAME_TOKEN10); assertPolicy(aim, SPConstants.USERNAME_TOKEN11); assertPolicy(aim, SPConstants.HASH_PASSWORD); assertPolicy(aim, SPConstants.NO_PASSWORD); assertPolicy(aim, SP13Constants.NONCE); assertPolicy(aim, SP13Constants.CREATED); return (UsernameToken) assertTokens(message, SPConstants.USERNAME_TOKEN, true); }
@Test public void testRequestorOutboundSoapAction() throws Exception { SoapMessage message = setUpMessage(); interceptor.handleMessage(message); control.verify(); Map<String, List<String>> reqHeaders = CastUtils.cast((Map<?, ?>) message.get(Message.PROTOCOL_HEADERS)); assertNotNull(reqHeaders); List<String> soapaction = reqHeaders.get("soapaction"); assertTrue(null != soapaction && soapaction.size() == 1); assertEquals("\"http://foo/bar/SEI/opReq\"", soapaction.get(0)); }
@Test public void testEncryptedUsernameToken() throws Exception { Map<String, String> outProperties = new HashMap<String, String>(); outProperties.put( WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.ENCRYPT); outProperties.put(WSHandlerConstants.ENC_PROP_FILE, "outsecurity.properties"); outProperties.put(WSHandlerConstants.USER, "alice"); outProperties.put("password", "alicePassword"); outProperties.put(WSHandlerConstants.ENCRYPTION_USER, "myalias"); outProperties.put( WSHandlerConstants.ENCRYPTION_PARTS, "{Content}{" + WSConstants.WSSE_NS + "}UsernameToken"); Map<String, String> inProperties = new HashMap<String, String>(); inProperties.put( WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.ENCRYPT); inProperties.put(WSHandlerConstants.DEC_PROP_FILE, "insecurity.properties"); inProperties.put( WSHandlerConstants.PW_CALLBACK_CLASS, "org.apache.cxf.ws.security.wss4j.TestPwdCallback"); List<String> xpaths = new ArrayList<String>(); xpaths.add("//wsse:Security"); SoapMessage inmsg = makeInvocation(outProperties, xpaths, inProperties); List<WSHandlerResult> handlerResults = getResults(inmsg); assertNotNull(handlerResults); assertSame(handlerResults.size(), 1); // // This should contain exactly 2 protection results // final java.util.List<WSSecurityEngineResult> protectionResults = handlerResults.get(0).getResults(); assertNotNull(protectionResults); assertSame(protectionResults.size(), 2); final Principal p1 = (Principal) protectionResults.get(0).get(WSSecurityEngineResult.TAG_PRINCIPAL); final Principal p2 = (Principal) protectionResults.get(1).get(WSSecurityEngineResult.TAG_PRINCIPAL); assertTrue(p1 instanceof UsernameTokenPrincipal || p2 instanceof UsernameTokenPrincipal); Principal utPrincipal = p1 instanceof UsernameTokenPrincipal ? p1 : p2; SecurityContext securityContext = inmsg.get(SecurityContext.class); assertNotNull(securityContext); assertSame(securityContext.getUserPrincipal(), utPrincipal); }
private UsernameToken assertTokens( SoapMessage message, UsernameTokenPrincipal princ, boolean signed) { AssertionInfoMap aim = message.get(AssertionInfoMap.class); Collection<AssertionInfo> ais = getAllAssertionsByLocalname(aim, SPConstants.USERNAME_TOKEN); UsernameToken tok = null; for (AssertionInfo ai : ais) { tok = (UsernameToken) ai.getAssertion(); ai.setAsserted(true); if ((tok.getPasswordType() == UsernameToken.PasswordType.HashPassword) && (princ == null || !princ.isPasswordDigest())) { ai.setNotAsserted("Password hashing policy not enforced"); } else { assertPolicy(aim, SPConstants.HASH_PASSWORD); } if ((tok.getPasswordType() != UsernameToken.PasswordType.NoPassword) && isNonEndorsingSupportingToken(tok) && (princ == null || princ.getPassword() == null)) { ai.setNotAsserted("Username Token No Password supplied"); } else { assertPolicy(aim, SPConstants.NO_PASSWORD); } if (tok.isCreated() && princ.getCreatedTime() == null) { ai.setNotAsserted("No Created Time"); } else { assertPolicy(aim, SP13Constants.CREATED); } if (tok.isNonce() && princ.getNonce() == null) { ai.setNotAsserted("No Nonce"); } else { assertPolicy(aim, SP13Constants.NONCE); } } assertPolicy(aim, SPConstants.USERNAME_TOKEN10); assertPolicy(aim, SPConstants.USERNAME_TOKEN11); assertPolicy(aim, SPConstants.SUPPORTING_TOKENS); if (signed || isTLSInUse(message)) { assertPolicy(aim, SPConstants.SIGNED_SUPPORTING_TOKENS); } return tok; }
private void storeResults(UsernameTokenPrincipal principal, SoapMessage message) { List<WSSecurityEngineResult> v = new ArrayList<WSSecurityEngineResult>(); int action = WSConstants.UT; if (principal.getPassword() == null) { action = WSConstants.UT_NOPASSWORD; } v.add(0, new WSSecurityEngineResult(action, principal, null, null, null)); List<WSHandlerResult> results = CastUtils.cast((List<?>) message.get(WSHandlerConstants.RECV_RESULTS)); if (results == null) { results = new ArrayList<WSHandlerResult>(); message.put(WSHandlerConstants.RECV_RESULTS, results); } WSHandlerResult rResult = new WSHandlerResult(null, v); results.add(0, rResult); assertTokens(message, principal, false); message.put(WSS4JInInterceptor.PRINCIPAL_RESULT, principal); }
protected void addToken(SoapMessage message) { UsernameToken tok = assertTokens(message); Header h = findSecurityHeader(message, true); WSSecUsernameToken utBuilder = addUsernameToken(message, tok); if (utBuilder == null) { AssertionInfoMap aim = message.get(AssertionInfoMap.class); Collection<AssertionInfo> ais = getAllAssertionsByLocalname(aim, SPConstants.USERNAME_TOKEN); for (AssertionInfo ai : ais) { if (ai.isAsserted()) { ai.setAsserted(false); } } return; } Element el = (Element) h.getObject(); utBuilder.prepare(el.getOwnerDocument()); el.appendChild(utBuilder.getUsernameTokenElement()); }
protected WSSecurityEngineResult validateToken(Element tokenElement, final SoapMessage message) throws WSSecurityException, Base64DecodingException { boolean bspCompliant = isWsiBSPCompliant(message); boolean allowNoPassword = isAllowNoPassword(message.get(AssertionInfoMap.class)); UsernameTokenProcessor p = new UsernameTokenProcessor(); WSDocInfo wsDocInfo = new WSDocInfo(tokenElement.getOwnerDocument()); RequestData data = new RequestData() { public CallbackHandler getCallbackHandler() { return getCallback(message); } public Validator getValidator(QName qName) throws WSSecurityException { Object validator = message.getContextualProperty(SecurityConstants.USERNAME_TOKEN_VALIDATOR); if (validator == null) { return super.getValidator(qName); } return (Validator) validator; } }; // Configure replay caching ReplayCache nonceCache = WSS4JUtils.getReplayCache( message, SecurityConstants.ENABLE_NONCE_CACHE, SecurityConstants.NONCE_CACHE_INSTANCE); data.setNonceReplayCache(nonceCache); WSSConfig config = WSSConfig.getNewInstance(); config.setAllowUsernameTokenNoPassword(allowNoPassword); data.setWssConfig(config); if (!bspCompliant) { data.setDisableBSPEnforcement(true); } List<WSSecurityEngineResult> results = p.handleToken(tokenElement, data, wsDocInfo); return results.get(0); }
@Test public void testRequestorOutboundDispatchedSoapAction() throws Exception { SoapMessage message = setUpMessage(); BindingOperationInfo dbop = setUpBindingOperationInfo( "http://foo/bar/d", "opDReq", "opDResp", SEI.class.getMethod("op", new Class[0])); SoapOperationInfo soi = new SoapOperationInfo(); soi.setAction("http://foo/bar/d/SEI/opDReq"); dbop.addExtensor(soi); BindingOperationInfo bop = message.getExchange().get(BindingOperationInfo.class); bop.setProperty("dispatchToOperation", dbop); interceptor.handleMessage(message); control.verify(); Map<String, List<String>> reqHeaders = CastUtils.cast((Map<?, ?>) message.get(Message.PROTOCOL_HEADERS)); assertNotNull(reqHeaders); List<String> soapaction = reqHeaders.get("soapaction"); assertTrue(null != soapaction && soapaction.size() == 1); assertEquals("\"http://foo/bar/d/SEI/opDReq\"", soapaction.get(0)); }
private void readHeaders(XMLStreamReader xmlReader, SoapMessage message) throws XMLStreamException { // read header portion of SOAP document into DOM SoapVersion version = message.getVersion(); XMLStreamReader filteredReader = new PartialXMLStreamReader(xmlReader, version.getBody()); Node nd = message.getContent(Node.class); W3CDOMStreamWriter writer = message.get(W3CDOMStreamWriter.class); Document doc = null; if (writer != null) { StaxUtils.copy(filteredReader, writer); doc = writer.getDocument(); } else if (nd instanceof Document) { doc = (Document) nd; StaxUtils.readDocElements(doc, doc, filteredReader, false, false); } else { doc = StaxUtils.read(filteredReader); message.setContent(Node.class, doc); } // get the actual SOAP header Element element = doc.getDocumentElement(); QName header = version.getHeader(); List<Element> elemList = DOMUtils.findAllElementsByTagNameNS( element, header.getNamespaceURI(), header.getLocalPart()); for (Element elem : elemList) { // set all child elements as headers for message transmission Element hel = DOMUtils.getFirstElement(elem); while (hel != null) { SoapHeader sheader = new SoapHeader(DOMUtils.getElementQName(hel), hel); message.getHeaders().add(sheader); hel = DOMUtils.getNextElement(hel); } } }
private List<WSHandlerResult> getResults(SoapMessage inmsg) { final List<WSHandlerResult> handlerResults = CastUtils.cast((List<?>) inmsg.get(WSHandlerConstants.RECV_RESULTS)); return handlerResults; }
public void handleMessage(Message m) throws Fault { if (!(m instanceof SoapMessage)) { return; } SoapMessage message = (SoapMessage) m; if (!message.hasHeaders()) { return; } Header mule_header = message.getHeader(MULE_HEADER_Q); if (mule_header == null) { return; } Object obj = mule_header.getObject(); if (!(obj instanceof Element)) { // Error? We can't work with it at any rate. return; } Element header_element = (Element) obj; NodeList mule_headers = header_element.getChildNodes(); int idx = 0; Node child; while ((child = mule_headers.item(idx++)) != null) { if (child.getNodeType() != Node.ELEMENT_NODE) { continue; } Element child_el = (Element) child; if (child_el.getNamespaceURI() == null || !child_el.getNamespaceURI().equals(MULE_NS_URI)) { continue; } if (SUPPORTED_HEADERS.contains(child_el.getLocalName())) { message.put(child_el.getLocalName(), collectTextFrom(child_el)); } } MuleMessage reqMsg = ((MuleEvent) message.getExchange().get(CxfConstants.MULE_EVENT)).getMessage(); // Copy correlation headers nto message String replyTo = (String) message.get(MuleProperties.MULE_REPLY_TO_PROPERTY); if (replyTo != null) { reqMsg.setReplyTo(replyTo); } String corId = (String) message.get(MuleProperties.MULE_CORRELATION_ID_PROPERTY); if (corId != null) { reqMsg.setCorrelationId(corId); } String corGroupSize = (String) message.get(MuleProperties.MULE_CORRELATION_GROUP_SIZE_PROPERTY); if (corGroupSize != null) { reqMsg.setCorrelationGroupSize(Integer.valueOf(corGroupSize)); } String corSeq = (String) message.get(MuleProperties.MULE_CORRELATION_SEQUENCE_PROPERTY); if (corSeq != null) { reqMsg.setCorrelationSequence(Integer.valueOf(corSeq)); } }
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); } }