@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);
  }
 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;
 }
  /** @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);
  }
  /**
   * 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"));
      }
    }
  }
  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());
    }
  }
  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);
      }
    }
  }
  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 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);
    }
  }
  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));
    }
  }
Beispiel #10
0
  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);
    }
  }