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

使用Axis2 Java客户端访问.NET服务:SecurityContextToken缺少sp:IncludeToken属性

解决Axis2 + Rampart处理WS-SecureConversation时的SecurityContextToken doesn't contain any sp:IncludeToken attribute异常

先给你拆解下这个问题的核心:你遇到的异常是因为Rampart在解析WS-SecureConversation的安全策略时,期望嵌套的SecurityContextToken(SCT)也带有sp:IncludeToken属性,但当前的WSDL或策略配置里没满足这个要求,或者Rampart版本存在解析bug。结合你的场景,给你几个可行的解决方案:

1. 检查WSDL的完整安全策略

你贴的WSDL片段只显示了sp:SecureConversationToken的IncludeToken属性,但需要确认这个节点下是否嵌套了sp:SecurityContextToken,并且这个SCT节点是否也带有sp:IncludeToken属性。如果WSDL里的SCT没有这个属性,Rampart 1.7.1的解析器会直接抛出这个异常。

如果有权限修改WSDL,可以补充这个属性,比如:

<sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
    <sp:SecurityContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
        <wsc:SecurityContextTokenType xmlns:wsc="http://schemas.xmlsoap.org/ws/2005/02/sc"/>
    </sp:SecurityContextToken>
    <!-- 其他相关策略节点 -->
</sp:SecureConversationToken>

2. 升级Rampart版本

你当前使用的是Rampart 1.7.1,这个版本对WS-SecureConversation的策略解析存在已知的兼容性问题。建议升级到Rampart 1.8.0(稳定版),新版本修复了不少策略解析的bug,大概率能解决这个属性缺失的报错。

3. 手动配置Rampart策略文件(绕过WSDL解析问题)

如果修改WSDL不可行,可以手动创建Rampart的配置文件,强制指定SCT的IncludeToken属性。步骤如下:

  • 创建rampart-config.xml文件,内容如下:
<rampart:RampartConfig xmlns:rampart="http://ws.apache.org/rampart/policy">
    <rampart:passwordCallbackClass>com.yourpackage.ClientPasswordCallback</rampart:passwordCallbackClass>
    <rampart:policy>
        <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
            <sp:SecureConversationToken xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy" 
                sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                <sp:SecurityContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                    <wsc:SecurityContextTokenType xmlns:wsc="http://schemas.xmlsoap.org/ws/2005/02/sc"/>
                </sp:SecurityContextToken>
            </sp:SecureConversationToken>
            <!-- 补充TransportWithMessageCredential相关的策略,比如HTTPS传输配置 -->
            <sp:TransportBinding>
                <wsp:Policy>
                    <sp:TransportToken>
                        <wsp:Policy>
                            <sp:HttpsToken RequireClientCertificate="false"/>
                        </wsp:Policy>
                    </sp:TransportToken>
                    <sp:AlgorithmSuite>
                        <wsp:Policy>
                            <sp:Basic256/>
                        </wsp:Policy>
                    </sp:AlgorithmSuite>
                    <sp:Layout>
                        <wsp:Policy>
                            <sp:Lax/>
                        </wsp:Policy>
                    </sp:Layout>
                    <sp:IncludeTimestamp/>
                </wsp:Policy>
            </sp:TransportBinding>
        </wsp:Policy>
    </rampart:policy>
</rampart:RampartConfig>
  • 在客户端代码中加载这个配置,替换原来直接设置用户名密码的部分:
ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(ClientRepo, AxisConfig);
IMSFeedManagerStub feed = new IMSFeedManagerStub(ctx, ServiceUrl);
ServiceClient sc = feed._getServiceClient();
sc.engageModule("rampart");

Options options = sc.getOptions();
// 加载自定义Rampart配置
options.setProperty(RampartMessageData.KEY_RAMPART_CONFIG, new File("path/to/rampart-config.xml").getAbsolutePath());

4. 改用PasswordCallback处理凭证

直接在Options中设置用户名密码的方式,在SecureConversation场景下可能不生效,建议实现PasswordCallback类来处理凭证:

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
import java.io.IOException;

public class ClientPasswordCallback implements CallbackHandler {
    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        WSPasswordCallback callback = (WSPasswordCallback) callbacks[0];
        // 设置用户名和密码
        callback.setIdentifier("apache");
        callback.setPassword("password");
    }
}

然后在rampart-config.xml中指定这个类的全路径,如上面配置里的rampart:passwordCallbackClass节点。

5. 确认ClientRepo的模块配置

确保你的ClientRepo目录下的modules/rampart.xml配置文件存在且完整,没有缺失依赖。如果是从Axis2的分发包中复制的,一般没问题,但如果是自定义的,需要检查是否包含了SecureConversation相关的配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:25:14