CXF策略验证程序禁用

时间:2017-03-03 11:16:16

标签: java cxf ws-security

所有

我正在与需要签名和政策的网络服务进行互动。

我使用绑定提供程序属性,回调处理程序,密钥库等设置我的CXF(3.1.6 wildfly捆绑)。

bp.getRequestContext().put(SecurityConstants.CALLBACK_HANDLER, new PasswordCallbackHandler());
                bp.getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIES, MyUtils.class.getClassLoader().getResource("crypto.properties"));

bp.getRequestContext().put(SecurityConstants.SIGNATURE_USERNAME, "client"); 

CXF负责提供wsdl中定义的所有必要策略。 通讯顺利,我发送请求并收到预期的回复。

但此时,CXF Policy验证程序抛出异常:

org.apache.cxf.ws.policy.PolicyException: These policy alternatives can not be satisfied: 
{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}SignedParts: Soap Body is not SIGNED
    at org.apache.cxf.ws.policy.AssertionInfoMap.checkEffectivePolicy(AssertionInfoMap.java:179)
    at org.apache.cxf.ws.policy.PolicyVerificationInInterceptor.handle(PolicyVerificationInInterceptor.java:102)
    at org.apache.cxf.ws.policy.AbstractPolicyInterceptor.handleMessage(AbstractPolicyInterceptor.java:44)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)

这是签署部分的合同:

    <sp:SignedParts>
        <sp:Body />
        <sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="ReplyTo" />
        <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />            
        <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
        <sp:Header Namespace="http://www.w3.org/2005/08/addressing" Name="Action" />
        <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />

    </sp:SignedParts>

收到回复:

...
      <ds:SignedInfo>
          <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
            <exc14n:InclusiveNamespaces PrefixList="wsse S"/>
          </ds:CanonicalizationMethod>
          <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
          <ds:Reference URI="#_5002">
            <ds:Transforms>
              <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <exc14n:InclusiveNamespaces PrefixList="S"/>
              </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>IirHgSUh19ly5qpPiXKVfMB2tZ4=</ds:DigestValue>
          </ds:Reference>
          <ds:Reference URI="#_5003">
            <ds:Transforms>
              <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <exc14n:InclusiveNamespaces PrefixList="S"/>
              </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>8SY6Wz36TUlZtY+31Z5EpESs5JM=</ds:DigestValue>
          </ds:Reference>
          <ds:Reference URI="#_5004">
            <ds:Transforms>
              <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <exc14n:InclusiveNamespaces PrefixList="S"/>
              </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>yvxtMZ3SC++ZOv0RPS/Ge9ETGHA=</ds:DigestValue>
          </ds:Reference>
          <ds:Reference URI="#_5005">
            <ds:Transforms>
              <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <exc14n:InclusiveNamespaces PrefixList="S"/>
              </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>t/slFuF8/W8sWGrrAuJTmtliCeU=</ds:DigestValue>
          </ds:Reference>
          <ds:Reference URI="#_5006">
            <ds:Transforms>
              <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <exc14n:InclusiveNamespaces PrefixList="S"/>
              </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>Cjcz1r8PMjV/04CLrMDpNx+e3ks=</ds:DigestValue>
          </ds:Reference>
          <ds:Reference URI="#_3">
            <ds:Transforms>
              <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <exc14n:InclusiveNamespaces PrefixList="wsu wsse S"/>
              </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>6htA73nOJBrYMteWrJ9pdag3cA8=</ds:DigestValue>
          </ds:Reference>
        </ds:SignedInfo>
     ...

  </S:Header>
  <S:Body>
    <ns2:getCallResponse xmlns:ns2="http://somenamespace/Schemas/" wsu:Id="_5006">

正如您所看到的,有一个对已签名部分的引用,但ID属性不在主体(如请求)级别,而是在子标记上。

我不知道这是否可能是问题,如果是服务器方面的问题,但服务是遗留的,而且无法改变它。

所以我的问题是:如何在SoapBody上禁用传入的策略验证器或特定的断言?

由于

2 个答案:

答案 0 :(得分:1)

在Colm O hEigeartaigh帮助之后,这是实施的决议。

属性设置:

 // Policy ovveride
        Map<QName, SecurityPolicyValidator> validatorMap = new HashMap<>();
        validatorMap.put(new QName("http://schemas.xmlsoap.org/ws/2005/07/securitypolicy", "SignedParts"), new FakeSecuredPartsValidator());
        bp.getRequestContext().put(SecurityConstants.POLICY_VALIDATOR_MAP, validatorMap);

基于CXF中原始验证器的假验证器:

public class FakeSecuredPartsValidator implements SecurityPolicyValidator {

 private CoverageType coverageType = CoverageType.ENCRYPTED;

    /**
 * Return true if this SecurityPolicyValidator implementation is capable of validating a
 * policy defined by the AssertionInfo parameter
 */
@Override
public boolean canValidatePolicy(AssertionInfo assertionInfo) {
    if (coverageType == CoverageType.SIGNED) {
        return assertionInfo.getAssertion() != null
            && (SP12Constants.SIGNED_PARTS.equals(assertionInfo.getAssertion().getName())
                || SP11Constants.SIGNED_PARTS.equals(assertionInfo.getAssertion().getName()));
    } else {
        return assertionInfo.getAssertion() != null
            && (SP12Constants.ENCRYPTED_PARTS.equals(assertionInfo.getAssertion().getName())
                || SP11Constants.ENCRYPTED_PARTS.equals(assertionInfo.getAssertion().getName()));
    }
}

/**
 * Validate policies, set all as validates
 */
@Override
public void validatePolicies(PolicyValidatorParameters parameters, Collection<AssertionInfo> ais) {
    //
    // SIGNED_PARTS and ENCRYPTED_PARTS only apply to non-Transport bindings
    //
    if (isTransportBinding(parameters.getAssertionInfoMap(), parameters.getMessage())) {
        return;
    }

    // Set asserted = true for all Assertions
    for (AssertionInfo ai : ais) {
        if (ai.isAsserted()) {
            // Secured Parts could already have been asserted by one of the other validators, if
            // they are a child of a SupportingToken
            continue;
        }

        ai.setAsserted(true);
    }
}

private boolean isTransportBinding(AssertionInfoMap aim, Message message) {
    AssertionInfo symAis = PolicyUtils.getFirstAssertionByLocalname(aim, SPConstants.SYMMETRIC_BINDING);
    if (symAis != null) {
        return false;
    }

    AssertionInfo asymAis = PolicyUtils.getFirstAssertionByLocalname(aim, SPConstants.ASYMMETRIC_BINDING);
    if (asymAis != null) {
        return false;
    }

    AssertionInfo transAis = PolicyUtils.getFirstAssertionByLocalname(aim, SPConstants.TRANSPORT_BINDING);
    if (transAis != null) {
        return true;
    }

    // No bindings, check if we are using TLS
    TLSSessionInfo tlsInfo = message.get(TLSSessionInfo.class);
    if (tlsInfo != null) {
        // We don't need to check these policies for TLS
        PolicyUtils.assertPolicy(aim, SP12Constants.ENCRYPTED_PARTS);
        PolicyUtils.assertPolicy(aim, SP11Constants.ENCRYPTED_PARTS);
        PolicyUtils.assertPolicy(aim, SP12Constants.SIGNED_PARTS);
        PolicyUtils.assertPolicy(aim, SP11Constants.SIGNED_PARTS);
        return true;
    }

    return false;
}

public CoverageType getCoverageType() {
    return coverageType;
}

public void setCoverageType(CoverageType coverageType) {
    this.coverageType = coverageType;
}

}

答案 1 :(得分:0)

服务不遵循规范,Body元素本身必须签名,而不是上面请求中的子元素。但是,最新版本的CXF允许您通过&#34; ws-security.policy.validator.map&#34;插入自定义验证逻辑。 JAX-WS属性。这是一个将QName映射到SecurityPolicyValidator实例的映射。因此,在您的情况下,您可以将SignedParts策略QName映射到默认SecuredPartsPolicyValidator的修改版本,以更改验证逻辑。