You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过WSDL4J为JAX-WS+Spring SOAP服务的WSDL添加wsp:Policy

用WSDL4J添加wsp:Policy到JAX-WS SOAP服务的WSDL

嘿,我来帮你搞定用WSDL4J给你的SOAP服务添加指定安全策略的事儿,咱们一步步来拆解:

1. 先搞定命名空间声明

首先,你的setNamespaces方法需要包含所有用到的命名空间(wsp、wsu、sp、wsaw),不然WSDL4J生成的文档会报错。示例代码如下:

private void setNamespaces(Definition definition) {
    // 安全策略相关命名空间
    definition.addNamespace("wsp", "http://schemas.xmlsoap.org/ws/2004/09/policy");
    definition.addNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
    definition.addNamespace("sp", "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702");
    definition.addNamespace("wsaw", "http://www.w3.org/2006/05/addressing/wsdl");
    
    // 保留你原本已有的其他命名空间(比如soap、wsdl等)
    // definition.addNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/");
    // ...
}

2. 实现setPolicy方法构建完整的安全策略

接下来就是核心的setPolicy方法,我们需要用WSDL4J的API逐层构建你需要的wsp:Policy结构:

private void setPolicy(Definition definition) {
    ElementFactory elementFactory = definition.getElementFactory();

    // 1. 创建根wsp:Policy元素,设置wsu:Id属性
    Policy policy = (Policy) elementFactory.createElement(Policy.QNAME);
    policy.setAttribute("wsu:Id", "UserNameWSTrustBinding_IWSTrust13Async_policy");

    // 2. 添加wsp:ExactlyOne容器
    ExactlyOne exactlyOne = (ExactlyOne) elementFactory.createElement(ExactlyOne.QNAME);
    policy.addExtensibilityElement(exactlyOne);

    // 3. 添加wsp:All容器
    All all = (All) elementFactory.createElement(All.QNAME);
    exactlyOne.addExtensibilityElement(all);

    // 4. 添加sp:TransportBinding(含内部wsp:Policy)
    TransportBinding transportBinding = createSecurityElement(definition, TransportBinding.QNAME);
    addInnerPolicyToElement(definition, transportBinding);
    all.addExtensibilityElement(transportBinding);

    // 5. 添加sp:SignedEncryptedSupportingTokens(含内部wsp:Policy)
    SignedEncryptedSupportingTokens signedEncryptedTokens = createSecurityElement(definition, SignedEncryptedSupportingTokens.QNAME);
    addInnerPolicyToElement(definition, signedEncryptedTokens);
    all.addExtensibilityElement(signedEncryptedTokens);

    // 6. 添加sp:EndorsingSupportingTokens(含内部wsp:Policy)
    EndorsingSupportingTokens endorsingTokens = createSecurityElement(definition, EndorsingSupportingTokens.QNAME);
    addInnerPolicyToElement(definition, endorsingTokens);
    all.addExtensibilityElement(endorsingTokens);

    // 7. 添加sp:Wss11并填充内容
    Wss11 wss11 = createSecurityElement(definition, Wss11.QNAME);
    populateWss11Content(definition, wss11);
    all.addExtensibilityElement(wss11);

    // 8. 添加sp:Trust13并填充内容
    Trust13 trust13 = createSecurityElement(definition, Trust13.QNAME);
    populateTrust13Content(definition, trust13);
    all.addExtensibilityElement(trust13);

    // 9. 添加wsaw:UsingAddressing
    QName usingAddressingQName = new QName("http://www.w3.org/2006/05/addressing/wsdl", "UsingAddressing");
    UsingAddressing usingAddressing = (UsingAddressing) elementFactory.createElement(usingAddressingQName);
    all.addExtensibilityElement(usingAddressing);

    // 10. 将Policy添加到WSDL定义中
    definition.addExtensibilityElement(policy);
}

辅助方法:通用安全元素创建

为了避免重复代码,我们可以写一个通用方法创建安全策略元素:

private <T extends ExtensibilityElement> T createSecurityElement(Definition definition, QName qname) {
    ElementFactory elementFactory = definition.getElementFactory();
    return (T) elementFactory.createElement(qname);
}

辅助方法:给元素添加内部wsp:Policy

比如sp:TransportBinding内部需要嵌套wsp:Policy,我们可以用这个方法填充:

private void addInnerPolicyToElement(Definition definition, ExtensibilityElement parent) {
    Policy innerPolicy = (Policy) definition.getElementFactory().createElement(Policy.QNAME);
    
    // 这里填充内部Policy的具体内容,比如以TransportBinding为例:
    TransportToken transportToken = createSecurityElement(definition, TransportToken.QNAME);
    HttpToken httpToken = createSecurityElement(definition, HttpToken.QNAME);
    transportToken.addExtensibilityElement(httpToken);
    innerPolicy.addExtensibilityElement(transportToken);
    
    // 可继续添加sp:AlgorithmSuite、sp:Layout等其他子元素
    // ...
    
    parent.addExtensibilityElement(innerPolicy);
}

辅助方法:填充sp:Wss11和sp:Trust13的内容

根据你的需求填充这两个元素的具体配置,示例如下:

private void populateWss11Content(Definition definition, Wss11 wss11) {
    // 添加sp:MustSupportRefKeyIdentifier等规则
    MustSupportRefKeyIdentifier refKeyId = createSecurityElement(definition, MustSupportRefKeyIdentifier.QNAME);
    wss11.addExtensibilityElement(refKeyId);
    // 其他Wss11配置项...
}

private void populateTrust13Content(Definition definition, Trust13 trust13) {
    // 添加sp:RequireClientEntropy等信任规则
    RequireClientEntropy clientEntropy = createSecurityElement(definition, RequireClientEntropy.QNAME);
    trust13.addExtensibilityElement(clientEntropy);
    // 其他Trust13配置项...
}

3. 将Policy关联到你的Binding

最后,你需要在setBindingForWSDLDefinition方法中添加Policy引用,把策略绑定到具体的服务Binding上:

private void setBindingForWSDLDefinition(Definition definition) {
    Binding binding = definition.createBinding();
    // 绑定的基础配置(名称、PortType关联等)
    binding.setQName(new QName("你的命名空间", "你的Binding名称"));
    binding.setPortType(definition.getPortType(new QName("你的命名空间", "你的PortType名称")));
    
    // 添加Policy引用,指向之前创建的Policy的Id
    PolicyReference policyRef = (PolicyReference) definition.getElementFactory().createElement(PolicyReference.QNAME);
    policyRef.setURI("#UserNameWSTrustBinding_IWSTrust13Async_policy");
    binding.addExtensibilityElement(policyRef);
    
    // 完成绑定的其他配置(比如SOAP绑定细节)
    // ...
}

注意事项

  • 确保你的WSDL4J版本支持这些安全策略元素,推荐使用1.6.3及以上版本。
  • 如果依赖缺失,可能需要引入WSS4J相关依赖来处理安全策略的元素构建。

内容的提问来源于stack exchange,提问作者yogsma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:18:30