如何为 WS-Security 生成 UsernameToken?

2024-03-19

我有一些 Web 服务(用 Java 编写),我需要在 .NET 中为其创建客户端。 Web 服务具有 WS-Security 并且需要密码摘要。 首先,我在 SoapUI 中测试了它,它适用于:

POST http://192.168.100.101:8181/services/ws/SomeService HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action="someMethod"
Content-Length: 971
Host: 192.168.100.101:8181
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

<soap:Envelope xmlns:not="http://existing-domain.com/op/integration/services" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Header>
    <wsse:Security 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-2C1E2DE2B61EBB94E115572099598331">
            <wsse:Username>SOME_LOGIN</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">rcSb6Hd8btcI9g6JvO7dGdiTBTI=</wsse:Password>
            <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">PCoVwJm9oEXtusx6gkMb7w==</wsse:Nonce>
            <wsu:Created>2019-05-07T06:19:19.824Z</wsu:Created>
        </wsse:UsernameToken>
    </wsse:Security>
   </soap:Header>
   <soap:Body>
      <not:someMethod/>
   </soap:Body>
</soap:Envelope>

在下一步中,我在 .NET 中准备了简单的客户端,并使用 Wireshark 检查它发送的内容:

POST /services/ws/SomeService HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action="someMethod"
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Host: 192.168.100.101:8181
Content-Length: 1124
Expect: 100-continue
Connection: Keep-Alive

<soap:Envelope xmlns:not="http://existing-domain.com/op/integration/services" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header>
    <wsse:Security 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 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-85707168-b5c6-47dc-93e9-45afa466fa2a" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <wsse:Username>SOME_LOGIN</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">g112a9eHPR1hXD4UH+Lh3o8JV/o=</wsse:Password>
        <wsse:Nonce>EiUbo2DbXMGhM26fT+ZkJQ==</wsse:Nonce>
        <wsu:Created>2019-05-07T06:27:59Z</wsu:Created>
      </wsse:UsernameToken>
    </wsse:Security>
  </soap:Header>
  <soap:Body>
    <not:someMethod />
  </soap:Body>
</soap:Envelope>

不幸的是我总是收到 500 状态代码和响应:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
    <soap:Body>
        <soap:Fault>
            <soap:Code>
                <soap:Value>soap:Sender</soap:Value>
                <soap:Subcode>
                    <soap:Value xmlns:ns1="http://ws.apache.org/wss4j">ns1:SecurityError</soap:Value>
                </soap:Subcode>
            </soap:Code>
            <soap:Reason>
                <soap:Text xml:lang="en">A security error was encountered when verifying the message</soap:Text>
            </soap:Reason>
        </soap:Fault>
    </soap:Body>
</soap:Envelope>

我很确定它的出现是因为授权问题(如果提供了错误的凭据,我在 SoapUI 中也会收到相同的消息)。

我的客户端中的部分是使用以下命令创建的:

UsernameToken t = new UsernameToken("SOME_LOGIN", "SOME_PASSWORD", PasswordOption.SendHashed);
string usernameTokenSection = t.GetXml(new XmlDocument()).OuterXml.ToString();

有几篇文章如何创建密码数字(Base64( SHA1(密码 + 随机数 + 创建) )), 随机数 (Base64(随机字符串)) 或创建日期,但我找不到是什么wsu:Id="UsernameToken-2C1E2DE2B61EBB94E115572099598331"以及如何创建它。上面的代码我从 UsernameToken 获取 xml 返回完整的部分,所以我决定使用它,但我注意到它附加了wsu:Id="SecurityToken-85707168-b5c6-47dc-93e9-45afa466fa2a"(代替wsu:Id="UsernameToken-2C1E2DE2B61EBB94E115572099598331")。我可以更改名称并删除-字符,但没有任何改变,我仍然收到 500 内部服务器错误消息“验证消息时遇到安全错误".

所以,我的问题是如何用正确的方式生成 UsernameToken 部分wsu:Id="UsernameToken-XXXXXXXXXXXXXXX"数据?它是什么 - 只是随机字符串或基于用户名和密码创建的一些哈希值?


知道了!我注意到从 .NET 客户端发送的 SOAP 没有属性EncodingType in Nonce节点。代码稍作修改后:

UsernameToken t = new UsernameToken("SOME_LOGIN", "SOME_PASSWORD", PasswordOption.SendHashed);
string usernameTokenSection = t.GetXml(new XmlDocument()).OuterXml.ToString().Replace("<wsse:Nonce", "<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\"");

一切正常!

.NET 客户端的完整代码:

public static void Execute()
{            
        UsernameToken usernameTokenSection = new UsernameToken("SOME_LOGIN", "SOME_PASSWORD", PasswordOption.SendHashed);

        HttpWebRequest request = CreateWebRequest();
        XmlDocument soapEnvelopeXml = new XmlDocument();
        soapEnvelopeXml.LoadXml(@"<soap:Envelope xmlns:not=""http://existing-domain.com/op/integration/services"" xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"">" +
              "<soap:Header>" +
                @"<wsse:Security 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"">"+
                    usernameTokenSection.GetXml(new XmlDocument()).OuterXml.ToString().Replace("<wsse:Nonce", "<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\"") +
                "</wsse:Security>" +
              "</soap:Header>"+
              "<soap:Body>"+
                "<not:someMethod/>"+
              "</soap:Body>"+
            "</soap:Envelope>");

        using (Stream stream = request.GetRequestStream())
        {
            soapEnvelopeXml.Save(stream);
        }

        using (WebResponse response = request.GetResponse())
        {
            using (StreamReader rd = new StreamReader(response.GetResponseStream()))
            {
                string soapResult = rd.ReadToEnd();
                Console.WriteLine(soapResult);
            }
        }
}

public static HttpWebRequest CreateWebRequest()
{
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(@"http://192.168.100.101:8181/services/ws/SomeService");

        webRequest.Method = "POST";
        webRequest.Headers.Add("Accept-Encoding:gzip,deflate");
        webRequest.ContentType = "application/soap+xml;charset=UTF-8;action=\"someMethod\"";
        //NOTE: below it's not necessary
        //webRequest.Host = "192.168.100.101:8181";
        //webRequest.KeepAlive = true;
        //webRequest.UserAgent = "Apache-HttpClient/4.1.1 (java 1.5)";

        return webRequest;
}

static void Main(string[] args)
{
        try
        {
            Execute();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            Console.ReadLine();
        }

}

附言。用于使用UsernameToken你必须使用的类Microsoft.Web.Services2参考,您可以从这里通过 Nuget 添加它:微软网络服务2 https://www.nuget.org/packages/Microsoft.Web.Services2/

聚苯硫醚。我知道有更简单的方法Add Service Reference...但它需要额外的类和修改来创建Security节点在Header,所以我决定发送原始 xml 并直接操作它。

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

如何为 WS-Security 生成 UsernameToken? 的相关文章

  • 当我单击 C# 中的“取消”按钮时重定向到新页面(Web 部分)

    Cancel button tc new TableCell btnCancel new Button btnCancel Text Cancel btnCancel Click new EventHandler btnCanel Clic
  • XML-RPC 和 SOAP 有什么区别?

    我从来没有真正理解为什么 Web 服务实施者会选择其中之一 XML RPC 通常出现在较旧的系统中吗 任何有助于理解这一点的帮助将不胜感激 差异 SOAP 更强大 并且更受软件工具供应商 MSFT NET Java 企业版等 的青睐 SOA
  • 在 C++11 中省略返回类型

    我最近发现自己在 C 11 模式下的 gcc 4 5 中使用了以下宏 define RETURN x gt decltype x return x 并编写这样的函数 template
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • VS30063:您无权访问 https://dev.azure.com

    我正在尝试在 asp net core 2 1 mvc 应用程序中使用以下代码连接 Azure DevOps Uri orgUrl new Uri https dev azure com xxxxx String personalAcces
  • 如何用 kevent() 替换 select() 以获得更高的性能?

    来自Kqueue 维基百科页面 http en wikipedia org wiki Kqueue Kqueue 在内核和用户空间之间提供高效的输入和输出事件管道 因此 可以修改事件过滤器以及接收待处理事件 同时每次主事件循环迭代仅使用对
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer
  • 禁用 LINQ 上下文的所有延迟加载或强制预先加载

    我有一个文档生成器 目前包含约 200 个项目的查询 但完成后可能会超过 500 个 我最近注意到一些映射表示延迟加载 这给文档生成器带来了一个问题 因为它需要根据生成的文档来访问所有这些属性 虽然我知道DataLoadOptions可以指
  • 单元测试失败,异常代码为 c0000005

    我正在尝试使用本机单元测试项目在 Visual Studios 2012 中创建单元测试 这是我的测试 TEST METHOD CalculationsRoundTests int result Calculations Round 1 0
  • 为什么 FTPWebRequest 或 WebRequest 通常不接受 /../ 路径?

    我正在尝试从 ftp Web 服务器自动执行一些上传 下载任务 当我通过客户端甚至通过 Firefox 连接到服务器时 为了访问我的目录 我必须指定如下路径 ftp ftpserver com AB00000 incoming files
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • C# 创建数组的数组

    我正在尝试创建一个将使用重复数据的数组数组 如下所示 int list1 new int 4 1 2 3 4 int list2 new int 4 5 6 7 8 int list3 new int 4 1 3 2 1 int list4
  • 用于从字符串安全转换的辅助函数

    回到 VB6 我编写了一些函数 让我在编码时无需关心字符串的 null 和 数字的 null 和 0 等之间的区别 编码时 没有什么比添加特殊情况更能降低我的工作效率了用于处理可能导致一些不相关错误的数据的代码 9999 10000 如果我
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • Resteasy 可以查看 JAX-RS 方法的参数类型吗?

    我们使用 Resteasy 3 0 9 作为 JAX RS Web 服务 最近切换到 3 0 19 我们开始看到很多RESTEASY002142 Multiple resource methods match request警告 例如 我们
  • 哪些属性有助于运行时 .Net 性能?

    我正在寻找可用于通过向加载器 JIT 编译器或 ngen 提供提示来确保 Net 应用程序获得最佳运行时性能的属性 例如我们有可调试属性 http msdn microsoft com en us library k2wxda47 aspx
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12

随机推荐

  • 向 UITextField 添加不可编辑的文本后缀

    我有一个 UITextField 我想添加一个 所有输入文本的后缀 用户不应该能够删除这个 或在其右侧添加文本 解决这个问题的最佳方法是什么 Use the UITextFieldDelegate http developer apple
  • 转置前导维度为 N 的一维数组

    如何在没有额外空间的情况下转置前导维度为 N 的一维数组 任何语言都可以 我的一维就地矩阵转置解决方案 mn M N M rows and N columns q mn 1 i 0 Index of 1D array that repres
  • Chrome 多功能框特殊字符抛出错误

    我正在编写一个基本的 Chrome 扩展程序 以通过 JSON 源在多功能框中添加建议 几乎所有输入的查询都会在建议下拉列表中显示预期的结果 然而 每当描述中返回与号 时 Chrome 就会抛出错误 抛出的错误读取 xmlParseEnti
  • 获取句柄并写入启动我们进程的控制台

    我怎样才能写入一些已经打开的控制台的标准输出 我通过这段代码找到了我需要的控制台 IntPtr ptr GetForegroundWindow int u GetWindowThreadProcessId ptr out u Process
  • C++ 相当于 Java 的 andThen() 函数来组合新函数

    在Java中 您可以执行以下代码 Function
  • XSLT 转换抛出错误

    我有如下的xml
  • 在 Java 中,如何使用继承来简化代码? (安卓开发)

    在各种活动中我都有非常相似的方法 例如 Override public void onClick View v switch v getId case R id ibHome Intent menuIntent new Intent v g
  • 如何使用 OpenCV 查找图像中三角形的方向

    我试图找到图像中三角形的方向 下面是图片 这些三角形指向上 下 左 右 这不是真实的图像 我已经使用精明的边缘检测来查找边缘 然后找到轮廓 然后膨胀的图像如下所示 我寻找方向的逻辑 我想使用的逻辑是 在三个角坐标中 如果我可以识别三角形的基
  • JavaScript 定界文档

    我需要 JavaScript 中类似heredoc的东西 您对此有什么想法吗 我需要跨浏览器功能 我找到了这个 heredoc div ul li a href zzz zzz a li ul div 我认为这对我有用 Try ES6 字符
  • 为什么 Scala 隐式将 Char 转换为 Int?

    看看scala的Predef对象 这是自动导入的 我发现跟随宝石 http www scala lang org docu files api scala Predef 24object html char2int 28Char 29 im
  • 进度对话框显示太晚

    我有一个应用程序 我想执行以下操作 显示带有按钮和 TextView 的活动 用户单击按钮 应用程序会显示一个进度对话框 应用程序调用网络服务来获取列表 进度对话框被隐藏 并且列表选择对话框出现以显示检索到的列表 用户选择列表中的一项 项目
  • “include_examples”和“it_behaves_like”有什么区别?

    在 RSpec 中 有什么区别it behaves like and include examples The 文档 https www relishapp com rspec rspec core v 2 14 docs example
  • 二项式系数的计算算法

    我需要一种在不耗尽内存的情况下计算组合的方法 这是我到目前为止所拥有的 public static long combination long n long k nCk return divideFactorials factorial n
  • Azure Function App忽略依赖关系

    我有一个连接到数据库的 Azure 函数 但它失败并显示以下消息 找不到类型或命名空间名称 Npgsql 您是否缺少 using 指令或程序集引用 In project json 我有以下声明 frameworks net46 depend
  • Jasmine 获取当前测试结果

    我正在使用 Jasmine 3 3 1 与 ProtractorJS 的组合 我的要求是存储每个规范 或描述 测试 的结果 并使用 afterEach 方法在 Testrail 系统中更新结果 我想将结果存储到变量 testResult 中
  • 如何同时对多个 SKSpriteNode 进行动画处理?

    我很新SpriteKit 我有一组节点需要一起移动到每个节点的不同点 在所有节点的动画完成后 我想做其他事情 我正在做这个UIView之前的组件 A UIView animateWithDuration completion 块正在提供我需
  • 将 React-Native (Web) 集成到 Django 中。如何为所有网址添加前缀?

    我正在使用反应导航并试图找出如何向所有端点添加前缀 跟随我的LinkingConfiguration这不符合我的要求 const prefixes Linking makeUrl app const prefixes example app
  • Android 12:BLE 扫描未找到任何设备

    我正在尝试将低功耗蓝牙应用程序 连接到自定义物理设备 升级到 Android 12 我已按照文档中的方式设置了所有内容 但它不起作用 权限
  • Android 对话框宽度

    我似乎无法控制对话框宽度 我有一个像这样的简单布局
  • 如何为 WS-Security 生成 UsernameToken?

    我有一些 Web 服务 用 Java 编写 我需要在 NET 中为其创建客户端 Web 服务具有 WS Security 并且需要密码摘要 首先 我在 SoapUI 中测试了它 它适用于 POST http 192 168 100 101