Java CXF策略验证程序禁用
全部 我正在与一个需要签名和策略的Web服务交互 我使用绑定提供程序属性、回调处理程序、密钥库等设置了我的CXF(绑定了3.1.6 wildfly)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
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;
}
}