从 C# 调用 Java WS

2024-06-22

我试图从 C# 程序调用用 Java 编写的 WebService。 如果我使用 SoapUi 调用 WS,我可以在 fiddler 中看到调用如下所示:

<soap:Envelope xmlns:ser="http://service.webservice.com" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
       <soap:Header>
           <wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"   xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
               <wsse:UsernameToken wsu:Id="UsernameToken-8684DEB94ABXXXXXXXXXX362973">
                   <wsse:Username>MyUserName</wsse:Username>
                   <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">MyPassword</wsse:Password>
                   <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">fjwe5h78k7vgheedRv21g==</wsse:Nonce>
                   <wsu:Created>2016-11-17T11:53:56.297Z</wsu:Created>
               </wsse:UsernameToken>
           </wsse:Security>
       </soap:Header>
       <soap:Body>
          <ser:getTrades>
                <ser:filter>
                <ser:fromValueDate>2015-03-23</ser:fromValueDate>
                <ser:toValueDate>2015-03-23</ser:toValueDate>
             </ser:filter>
          </ser:getTrades>
       </soap:Body>
</soap:Envelope>

问题是 VisualStudio 创建的类没有标题选项

// CODEGEN: The optional WSDL extension element 'Policy' from namespace 
'http://schemas.xmlsoap.org/ws/2004/09/policy' was not handled.

那么如何添加带有用户名和密码的 Soap 标头以在 C# 中进行调用?

我也一直在寻找使用 WCF 和 wsdl (这里是部分)

    .
    .
    .
    <wsdl:binding name="TradeRetrieverServiceSOAP12Binding" type="ns0:TradeRetrieverServicePortType">
    <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" Id="UsernameTokenOverHTTPS">
    <wsp:ExactlyOne>
    <wsp:All>
    <sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
    <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>
    </wsp:Policy>
    </sp:TransportBinding>
    <sp:SignedSupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
    <wsp:Policy>
    <sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"/>
    </wsp:Policy>
    </sp:SignedSupportingTokens>
    </wsp:All>
    </wsp:ExactlyOne>
    </wsp:Policy>
    .
    .

它创建了这个绑定:

    <system.serviceModel>
        <bindings>
          <customBinding>
            <binding name="TradeRetrieverServiceSOAP12Binding">
              <security defaultAlgorithmSuite="Default" authenticationMode="UserNameOverTransport"
                requireDerivedKeys="true" securityHeaderLayout="Lax" includeTimestamp="false">
                <localClientSettings detectReplays="false" />
                <localServiceSettings detectReplays="false" />
              </security>
              <textMessageEncoding messageVersion="Soap12" />
              <httpsTransport />
            </binding>
          </customBinding>
        </bindings>
        <client>
          <endpoint address="http://Myservices/TradeRetrieverService"
            binding="customBinding" bindingConfiguration="TradeRetrieverServiceSOAP12Binding"
            contract="ServiceReference1.TradeRetrieverServicePortType" name="TradeRetrieverServiceSOAP12port_http" />
        </client>
    </system.serviceModel>

但这给了我这个错误:

    The provided URI scheme 'http' is invalid; expected 'https'.
    Parameter name: via

url 是 http 而不是 https

所以我这里有货。有任何想法吗?

EDIT

我现在获取数据,在 fiddler 中,在代码中我收到此错误: 命名空间 ' 中的标头 'Security'http://docs.oasis- http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' 此消息的接收者无法理解,导致消息无法处理。
此错误通常表明此消息的发送方启用了接收方无法处理的通信协议。 请确保客户端绑定的配置与服务绑定的配置一致。


遗憾的是,Microsoft 决定取消 WCF 中对 WSSecurity / UsernameTokens 的支持。当我几周前遇到同样的问题时,我深入研究了这个问题,但找不到他们为什么这样做。但只要付出一点努力,就有希望。

首先,如果您不想使用 HTTPS,则需要在绑定中指定(您指定了 https)。例如,我的绑定(也仅使用 HTTP)看起来非常简单:

<customBinding>
  <binding name="dummySoapBinding">
     <textMessageEncoding writeEncoding="UTF-8" messageVersion="Soap11" />
     <httpTransport />
  </binding>
</customBinding>

之后,为了在请求中创建必要的 WSS 安全标头,我定义了一个应用于端点的自定义行为。此行为将 MessageInspector 附加到发送请求的 ClientRuntime。该消息检查器在发送之前更改消息,并添加安全标头。您可以找到一些有关自定义行为的信息here https://blogs.msdn.microsoft.com/carlosfigueira/2011/06/28/wcf-extensibility-behavior-configuration-extensions/。有关消息检查器的信息可用here https://blogs.msdn.microsoft.com/carlosfigueira/2011/04/18/wcf-extensibility-message-inspectors/.

我的 MessageInspector 目前看起来像这样:

public string Username { get; set; }

public string Password { get; set; }

public PasswordDigestMessageInspector(string username, string password)
{
    Username = username;
    Password = password;
}

public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
    // do nothing
}

public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
    // generate token
    var usernameToken = new UsernameToken(this.Username, this.Password, PasswordOption.SendHashed);

    // save token as xml
    var securityToken = usernameToken.GetXml(new XmlDocument());
    var securityTokenText = securityToken.OuterXml;

    // remove vs data
    var limit = request.Headers.Count;
    for (var i = 0; i < limit; ++i)
    {
        if (!request.Headers[i].Name.Equals("VsDebuggerCausalityData")) continue;

        request.Headers.RemoveAt(i);
        break;
    }

    // set encoding type for nonce
    var nonceRegex = new Regex(@"<wsse:Nonce");
    securityTokenText = nonceRegex.Replace(securityTokenText,
        "<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\"");

    var newDoc = new XmlDocument();
    newDoc.LoadXml(securityTokenText);

    // create security header from message
    var securityHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", newDoc.DocumentElement, false);

    // add header to request message
    request.Headers.Add(securityHeader);

    // complete
    return Convert.DBNull;
}

我在这里使用的 UsernameToken 类包含您需要的一切。它曾在 WCF 之前使用过,但遗憾的是已被删除。该类定义于:Microsoft.Web.Services3.Security.Tokens。应该有 nuget 包。或者,您可以手动安装 Microsoft 的 WebService Enhancements (WSE) 3.0 (here https://www.microsoft.com/en-us/download/details.aspx?id=14089).

有一些额外的逻辑可以修改一些参数,以便我调用的 WebService 接受我的请求。它非常严格,我没有办法修改它。你可能可以忽略这一点。

继续,我添加到端点的行为如下所示:

public class PasswordDigestBehaviour : IEndpointBehavior
{
    public string Username { get; set; }

    public string Password { get; set; }

    public PasswordDigestBehaviour(string username, string password)
    {
        Username = username;
        Password = password;
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
        // do nothing
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new PasswordDigestMessageInspector(this.Username, this.Password));
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    {
        // do nothing
    }

    public void Validate(ServiceEndpoint endpoint)
    {
        // do nothing
    }
}

很简单。 最后,您可以将行为附加到 WCF 客户端类:

client.Endpoint.Behaviors.Add(new PasswordDigestBehaviour("Testuser", "Testpassword"));

我希望它能为您节省一些时间,因为我最近在这个话题上遇到了很多麻烦。

编辑:我刚刚看到您没有发送散列密码。您必须在“UsernameToken”的构造函数中考虑这一点,因为我正在对其进行哈希处理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 C# 调用 Java WS 的相关文章

  • MVC。网络错误:初始化字符串的格式不符合从索引 0 开始的规范

    我的连接字符串是
  • gets 和 scanf 有什么区别?

    如果代码是 scanf s n message vs gets message 有什么区别 似乎两者都获取消息的输入 基本区别 参考您的特定场景 scanf 遇到一个时结束接受输入whitespace newline or EOF gets
  • 在 2 个 .c 文件之间共享函数

    dir1有dir2 file1 c和file1 h dir2 有 file2 c 现在 如果我想在 file2 c 中访问 file1 c 中定义的函数 我需要在 file1 h 中声明它并在 file2 c 中包含 file1 h 这是一
  • 在子目录中构建共享库

    我正在尝试构建一个使用一些 C 代码的 R 包 我有一个编译为可执行文件的 C 库 可以从命令行调用 有一个与之关联的 Makefile 我正在尝试获取信息here http cran r project org doc manuals R
  • 运行时两个注册之间的简单注入器基于动态上下文的注入

    我有一个使用 Simple Injector 进行命令处理程序注册的中介应用程序 并且注入和处理程序均已设置并完美运行 class DoWashingCommandHandler IRequestHandler
  • 如何从 std::vector 中删除元素而不调整其大小

    迭代器擦除 迭代器位置 迭代器擦除 首先是迭代器 迭代器最后 擦除元素 从向量中删除 容器可以是单个元素 位置 或一系列元素 第一个 最后一个 这有效地减少了向量 大小除以元素数量 删除 调用每个元素的 之前的析构函数 and remove
  • 在宏中使用 # [重复]

    这个问题在这里已经有答案了 请解释一下代码 include
  • 指向指针的指针和指向二维数组的指针之间的区别

    如果我有一个二维数组 B 定义为 int B 2 3 1 3 5 2 4 6 Is int p B与 一样int p 3 B int f B printf d f 1 gives 5作为输出 同时printf d f 给出 1 作为答案 为
  • 如何处理作为参数传递到方法中的 Lambda 表达式 - C# .NET 3.5

    我对 Lambda 表达式的了解有点不稳定 虽然我可以编写使用 Lambda 表达式 又名 LINQ 的代码 但我正在尝试编写自己的方法 该方法采用一些 Lambda 表达式类型的参数 背景 我正在尝试编写一个方法 该方法从任何其他对象类型
  • 如何将 QSerialPort 模块添加到 CMake 中?

    我想将 QSerialPort 模块添加到 CMake 中 根据我的理解 我需要将QT 串口添加到 pro中 我只想使用 CMake 所以我尝试编译简单的 CMake 文件 但有错误 QtCore 正在工作 qDebug 可以毫无问题地显示
  • MVVM 同步集合

    是否有一种标准化方法可以将 Model 对象集合与 C 和 WPF 中匹配的 ModelView 对象集合同步 我正在寻找某种类 可以使以下两个集合保持同步 假设我只有几个苹果 并且可以将它们全部保存在内存中 换句话说 我想确保如果我将 A
  • 测试从 ComboBox 派生的自定义控件

    我创建了一个从 ComboBox 派生的控件 并希望对其行为进行单元测试 但是 它在我的单元测试中的行为似乎与实际应用程序中的行为不同 在实际应用程序中 Combobox DataSource 属性和 Items 同步 换句话说 当我更改
  • ASP.NET 中的 thread.sleep

    我正在为我的网站模拟彗星实时馈送协议 因此在我的控制器中我添加 while nothing new before timeout Thread Sleep 1000 但我注意到添加此功能后整个网站变慢了 调试后我得出结论 当我打电话时Thr
  • 如何在 WCF 中反序列化自定义 SOAP 标头?

    我正在尝试向通过 WCF 的所有 SOAP 请求添加自定义标头 我发现这篇精彩的文章 http blogs msdn com b mohamedg archive 2012 10 21 adding custom soap headers
  • UWP - 绑定枚举差异

    我遇到了一个非常有趣的问题 假设 UWP 应用中有以下 XAML 页面内容
  • 如何在 C++ 中初始化嵌套类的构造函数

    我在初始化嵌套类构造函数时遇到问题 这是我的代码 include
  • 简单的喷射器将具体类型与生活方式结合起来

    我正在寻找一种可以使用指定的生活方式注册具体类型的方法 基本上如下所示 public void SomeFunction Type concrete Lifestyle lifestyle gt container Register con
  • 如何进行平衡组捕获?

    假设我有这个文本输入 tes tR R abc aD mnoR xyz 我想提取 ff 输出 R abc R xyz D mnoR xyz R R abc aD mnoR xyz 目前 我只能使用平衡组方法提取组内的内容 如中所示msdn
  • 矩阵行列式算法 C++

    我是编程新手 我一直在寻找一种找到矩阵行列式的方法 我在网上找到了这段代码 但我很难理解这里的算法 我对递归的基础没有问题 但继续和主循环我很难理解 非常感谢任何可以向我解释该算法的人 int determ int a MAX MAX in
  • 使用反射检测属性的访问修饰符类型

    我编写了一些代码来使用反射查看属性 我已经使用反射从类中检索了属性列表 但是我需要查明该财产是公共的还是受保护的 例如 public string Name get set protected int Age get set Propert

随机推荐

  • 什么时候多线程不是一个好主意? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 为什么 AngularJS 不在其 isArray 函数中使用 instanceof ?

    来自 AngularJSisArray source return toString call value object Array 他们为什么不一起去 return value instanceof Array 因为如果你从不同的地方收到
  • Seaborn 与 Anaconda 一起提供吗?

    我正在尝试在 Spyder 上使用 Seaborn 作为 Anaconda 的一部分安装 import seaborn as sb returns 导入错误 没有名为seaborn的模块 尽管 Anaconda 网站将 Seaborn 列为
  • CORS 和 ASP.Net Web API

    我正在尝试在 asp net web api 中设置 CORS 我的 WebApiConfig cs 是 using System using System Collections Generic using System Linq usi
  • 有效地分割数据并拟合分布

    对于一个项目 我收到了大量机密的患者级别数据 我需要对这些数据进行分布拟合 以便在模拟模型中使用它 我正在使用 R 问题是我需要拟合分布以获得至少 288 个独立分布 至少 6 个变量的 48 个子集 的形状 速率数据 该过程在变量之间会略
  • ActivityNotFoundException,图像捕获?

    我发布了一个应用程序 用户可以在其中拍照 我这样做是为了拍摄照片 File file new File path Uri outputFileUri Uri fromFile file Intent intent new Intent an
  • Powershell 中使用 --runtime 命令设置 Jenkins 管道时出现的问题

    我正在尝试使用 Jenkins 配置管道并将其部署到 Azure 我正处于教程的最后一步 https learn microsoft com en us azure jenkins tutorial jenkins deploy web a
  • 如何检查引导模式是否打开,以便我可以使用 jquery 验证?

    仅当模态打开时我才需要进行验证 因为如果我打开它 然后关闭它 然后我按下打开模态的按钮 它就不起作用 因为它正在进行 jquery 验证 但不是显示是因为模式被驳回 所以我想在模态打开时添加一个jquery 以便我进行验证 这可能吗
  • SQLAlchemy 无法连接到本地主机上的 Postgresql

    我确信这是一个很容易修复的错误 只要我能找到它在哪里 这是 Flask 应用程序的错误 11 58 18 web 1 ERROR xxxxxx core Exception on GET 11 58 18 web 1 Traceback m
  • 无法将 MvcHtmlString/IHtmlString 与 RazorEngine 一起使用

    我刚刚开始使用 RazorEngine 在使用静态辅助方法时遇到了困难 它只是为模板生成一个 MvcHtmlString IHtmlString 当调用 Razor Parse 时我得到 RazorEngine Templating Tem
  • 查找 ArrayList 中重复值的索引

    我有一个 ArrayList 其中包含 diff diff 索引处的重复值 例如 Indian American Chinese Australian Indian Russian Indian 正如你所看到的价值 Indian 存在于索引
  • 使用 pip 和requirements.txt 安装链式依赖项?

    我正在尝试使用requirements txt 文件来使用pip 安装几个库 我的问题是一个图书馆 pyfasttext 需要另一个 Cython 首先要安装 如果我将两者放在同一个需求文件中 则安装pyfasttext失败了ImportE
  • 找不到 Fragment 构造函数

    我在某些设备上遇到了这个问题 并且我的崩溃分析出现错误 许多用户设备都面临这个问题 但在我的设备上它工作正常 无法启动活动 ComponentInfo com ox outloks new com ox outloks new activi
  • 使用 mysql 准备语句执行多个分号分隔的查询

    我试图在 mysql 中创建一个存储过程 它在每个请求上创建一个新表 从另一个表复制内容并提取所需的数据 最后删除该表 存储过程非常大 因此我无法在每个查询后执行 EXECUTE 因此我尝试以分号分隔的格式一起执行查询 但在最终执行时我得到
  • 在类型级别未定义

    通常 当我使用 Haskell 代码时 我会使用类型注释将内容存根并undefined foo String gt Int foo undefined 是否有类型级别的 未定义 我可以以类似的方式使用 理想情况下 与某种注释结合使用 typ
  • Facebook 对象调试器 - 无法将主机名解析为有效的 IP 地址

    Facebook 如何抓取我的页面以获取元数据存在问题 When I use the Facebook object debugger I get the following error 我很确定这与我的 DNS 记录的定义方式有关 看来抓
  • Flask-SQLAlchemy。创建多个所有字段相同的表

    我正在使用 Flask 及其 SQLAlchemy 扩展 我需要定义几个模型类 它们将在 MySQL 数据库中创建表 这些表仅在名称上有所不同 其中的所有字段名称 数据类型都相同 如何定义所有这些表的类 我正在考虑一些继承 但我不太确定我到
  • 如何在java中以编程方式将doc、docx文件转换为pdf

    我可以使用 docx4j 从 docx 文件生成 pdf 但是我需要将 doc 文件转换为 pdf 包括图像和表格 有没有办法在java中将doc转换为docx 或 doc 到 pdf docx4j 包含 org docx4j conver
  • 如何为 C 和 C++ 制作 makefile,源代码位于子目录中

    我有一个项目目前在 OS X 上的 Xcode 中构建 我正在尝试构建一个 makefile 以允许它在其他 Un x 系统上构建 我是编写 makefile 的新手 所以我一直根据网络上的各种示例拼凑出一个 makefile 也许并不奇怪
  • 从 C# 调用 Java WS

    我试图从 C 程序调用用 Java 编写的 WebService 如果我使用 SoapUi 调用 WS 我可以在 fiddler 中看到调用如下所示