Java CXF策略验证程序禁用

Java CXF策略验证程序禁用,java,cxf,ws-security,Java,Cxf,Ws Security,全部 我正在与一个需要签名和策略的Web服务交互 我使用绑定提供程序属性、回调处理程序、密钥库等设置了我的CXF(绑定了3.1.6 wildfly) bp.getRequestContext().put(SecurityConstants.CALLBACK_HANDLER, new PasswordCallbackHandler()); bp.getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIE

全部

我正在与一个需要签名和策略的Web服务交互

我使用绑定提供程序属性、回调处理程序、密钥库等设置了我的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策略验证程序抛出一个异常:

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">
。。。
IirHgSUh19ly5qpPiXKVfMB2tZ4=
8SY6Wz36TUlZtY+31Z5EpESs5JM=
yvxtMZ3SC++ZOv0RPS/Ge9ETGHA=
t/slFuF8/W8sWGrrAuJTmtliCeU=
Cjcz1r8PMjV/04CLrMDpNx+e3ks=
6htA73nOJBrYMteWrJ9pdag3cA8=
...
如您所见,有一个对签名部分的引用,但ID属性不在body(与请求类似)级别,而是在child标记上

我不知道这是否是个问题,如果是服务器端的问题,但服务是遗留的,没有办法改变它

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


谢谢

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

在Colm O HeigeraTaigh帮助之后,这是实现的解决方案

属性设置:

 // 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);
//策略ovveride
Map validatorMap=newhashmap();
validatorMap.put(新的QName(“http://schemas.xmlsoap.org/ws/2005/07/securitypolicy“,”签名零件“),新的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;
}
公共类FakeSecuredPartsValidator实现SecurityPolicyValidator{
私有CoverageType CoverageType=CoverageType.ENCRYPTED;
/**
*如果此SecurityPolicyValidator实现能够验证
*由AssertionInfo参数定义的策略
*/
@凌驾
公共布尔canValidatePolicy(断言信息断言信息){
if(coverageType==coverageType.SIGNED){
返回assertionInfo.getAssertion()!=null
&&(SP12Constants.SIGNED_PARTS.equals(assertionInfo.getAssertion().getName())
||SP11Constants.SIGNED_PARTS.equals(assertionInfo.getAssertion().getName());
}否则{
返回assertionInfo.getAssertion()!=null
&&(SP12Constants.ENCRYPTED_PARTS.equals(assertionInfo.getAssertion().getName())
||SP11Constants.ENCRYPTED_PARTS.equals(assertionInfo.getAssertion().getName());
}
}
/**
*验证策略,将所有设置为验证
*/
@凌驾
公共void validatePolicys(PolicyValidatorParameters、集合AI){
//
//签名的\u部分和加密的\u部分仅适用于非传输绑定
//
if(isTransportBinding(parameters.getAssertionInfoMap(),parameters.getMessage()){
返回;
}
//对于所有断言,Set asserted=true
用于(断言信息ai:ais){
if(ai.isAsserted()){
//安全部件可能已经由其他验证器之一声明,如果
//他们是一个支持者的孩子
继续;
}
ai.setAsserted(真);
}
}
私有布尔isTransportBinding(断言信息映射目标,消息){
AssertionInfo symAis=PolicyUtils.getFirstAssertionByLocalname(aim、SPConstants.SYMMETRIC_绑定);
如果(symAis!=null){
返回false;
}
AssertionInfo asymAis=PolicyUtils.getFirstAssertionByLocalname(aim、SPConstants.Asymetric_绑定);
if(asymAis!=null){
返回false;
}
AssertionInfo transAis=PolicyUtils.getFirstAssertionByLocalname(aim、SPConstants.TRANSPORT\u绑定);
if(transAis!=null){
返回true;
}
//没有绑定,请检查是否使用TLS
TLSSessionInfo tlsInfo=message.get(TLSSessionInfo.class);
如果(tlsInfo!=null){
//我们不需要检查TLS的这些策略
PolicyUtils.assertPolicy(aim,SP12Constants.ENCRYPTED_PARTS);
PolicyUtils.assertPolicy(aim,SP11 constants.ENCRYPTED_PARTS);
PolicyUtils.assertPolicy(aim,SP12 Constants.SIGNED_PARTS);
PolicyUtils.assertPolicy(aim、SP11协议、已签署部分);
返回true;
}
返回false;
}
公共CoverageType getCoverageType(){
返回coverageType;
}
public void setCoverageType(CoverageType CoverageType){
this.coverageType=coverageType;
}
}