简体   繁体   English

SOAP消息错误的C#安全凭证-WS-Security(WSS)

[英]C# Security Credentials to a SOAP Message ERROR - WS-Security (WSS)

I am trying to call a method on a WebReference (web-service) client that must use WS-Security. 我试图在必须使用WS-Security的WebReference(网络服务)客户端上调用方法。 When i execute the cargaFicheiro method it returns the following error: 当我执行cargaFicheiro方法时,它将返回以下错误:

An invalid security token was provided (An error happened processing a Username Token). 提供了无效的安全令牌(处理用户名令牌时发生错误)。

The code i'm using is: 我正在使用的代码是:

// Cuidamos is a WebReference do a WSDL url in https

var token = new UsernameToken("Username", "Password", PasswordOption.SendPlainText);

var serviceProxy = new Cuidamos.CargaFicheiroServiceImplService();

SoapContext requestContext = serviceProxy.RequestSoapContext;
requestContext.Security.Timestamp.TtlInSeconds = 300;
requestContext.Security.Tokens.Add(token);

var result = serviceProxy.cargaFicheiro();

The SOAP header must match this one: SOAP标头必须与此匹配:

<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" soap:mustUnderstand="1">
        <wsu:Timestamp wsu:Id="TS-2">
            <wsu:Created>2013-10-07T10:13:52Z</wsu:Created>
            <wsu:Expires>2013-10-07T10:20:32Z</wsu:Expires>
        </wsu:Timestamp>
        <wsse:UsernameToken wsu:Id="UsernameToken-1">
            <wsse:Username>USERNAME</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">PASSWORD</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
</soap:Header>

I have used the following answer to implement my code: https://stackoverflow.com/a/40030906/2449703 我已经使用以下答案来实现我的代码: https : //stackoverflow.com/a/40030906/2449703

Based on Microsoft i am doing all in the right way: https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-1.1/ms819938(v=msdn.10) 基于Microsoft,我以正确的方式做所有事情: https : //docs.microsoft.com/zh-cn/previous-versions/dotnet/netframework-1.1/ms819938(v=msdn.10)

Again other answer that works, but not in my case: https://forums.asp.net/t/2133187.aspx?C+oasis+Username+token 同样,其他答案也可行,但不适用于我的情况: https//forums.asp.net/t/2133187.aspx?C + oasis + Username + token

Thanks. 谢谢。

WSSE Nonce is a security attribute with a unique identifier designed to prevent replay attacks. WSSE Nonce是一个安全属性,具有唯一的标识符,旨在防止重放攻击。 Your server is likely generating this because you have a custom service binding configured in your service config. 您的服务器可能会生成此消息,因为您在服务配置中配置了自定义服务绑定。

It should work exactly once,which is likely why you can't re-use it from SOAPUI 它应该只工作一次,这可能就是为什么您不能从SOAPUI重用它的原因

More info here: 更多信息在这里:

https://weblog.west-wind.com/posts/2012/nov/24/wcf-wssecurity-and-wse-nonce-authentication https://weblog.west-wind.com/posts/2012/nov/24/wcf-wssecurity-and-wse-nonce-authentication

My question is almost solved. 我的问题几乎解决了。

I have notice that the SOAP Header generated by this code is the following: 我注意到此代码生成的SOAP标头如下:

<soapenv:Header>
    <wsa:Action></wsa:Action>
    <wsa:MessageID>uuid:2eead708-03f9-4624-a866-35f3730eac23</wsa:MessageID>
    <wsa:ReplyTo>
        <wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
    </wsa:ReplyTo>
    <wsa:To>https://cuidamos.com/ws/cuidamos</wsa:To>
    <wsse:Security soapenv:mustUnderstand="1">
        <wsu:Timestamp wsu:Id="Timestamp-64f67137-f82d-4a9c-8b2e-1cc41104683d">
            <wsu:Created>2019-06-27T12:48:00Z</wsu:Created>
            <wsu:Expires>2019-06-27T12:53:00Z</wsu:Expires>
        </wsu:Timestamp>
        <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-b8467c25-c62c-406a-9831-46e6c676153a">
            <wsse:Username>Username</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Password</wsse:Password>
            <wsse:Nonce>JEmovy7RDpapzumPTiUUgQ==</wsse:Nonce>
            <wsu:Created>2019-06-27T12:48:00Z</wsu:Created>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>

And i have used this solution to trace my request soap message. 我已经使用解决方案来跟踪我的请求肥皂消息。

But when i use SoapUI application to make a request with this SOAP Header, i have notice that if i remove <wsse:Nonce> element it will work just fine. 但是,当我使用SoapUI应用程序对此SOAP Header发出请求时,我注意到如果删除<wsse:Nonce>元素,它将很好地工作。 So i need to remove this <wsse:Nonce> element that is being dynamically generated and this is where i am working on, but don't know hot do it yet. 所以我需要删除正在动态生成的<wsse:Nonce>元素,这是我正在研究的地方,但是还不知道现在要这样做吗。

EDIT 编辑

I'm almost there, i have found that if i create the attribute EncodingType inside Nonce element it works, i don't need to remove Nonce element. 我快到了,我发现如果在Nonce元素内创建属性EncodingType可以正常工作,则无需删除Nonce元素。 This has been tested on SoapUI. 这已经在SoapUI上进行了测试。

The Nonce element should be created like this, the innerText on Nonce element is a hash string (SHA-1) created on each request: 应该像这样创建Nonce元素,Nonce元素上的innerText是在每个请求上创建的哈希字符串(SHA-1):

<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">6OX8gvIRETEbzaCwZ4byn/NEpzDI=</wsse:Nonce> <wsse:Nonce EncodingType =“ http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary”> 6OX8gvIRETEbzaCwZ4byn / NEpzDI = </ wsse:随机数>

To achive this result i have created dynamically UsernameToken with XML: 为了达到这个结果,我用XML动态创建了UsernameToken:

XmlDocument document = new XmlDocument();
XmlElement usernameTokenElement = document.CreateElement("wsse", "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

XmlElement usernameChild;
usernameChild = document.CreateElement("wsse", "Username", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
usernameChild.InnerText = "WSMASSIT";
usernameTokenElement.AppendChild(usernameChild);

XmlElement passwordChild;
passwordChild = document.CreateElement("wsse", "Password", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
passwordChild.SetAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
passwordChild.InnerText = "AstWs218";
usernameTokenElement.AppendChild(passwordChild);

string phrase = Guid.NewGuid().ToString();
var nonce = GetSHA1String(phrase); // User Function to create SHA-1 Hash String

XmlElement nonceChild;
nonceChild = document.CreateElement("wsse", "Nonce", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
nonceChild.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
nonceChild.InnerText = nonce;
usernameTokenElement.AppendChild(nonceChild);

var token = new UsernameToken(usernameTokenElement);

Now i have other problem, the Username and Password childs are created with success, but Nonce child is rewritten on runtime, wich means that Username and Password are created exactly as i coded but Nonce continues to be created without EncondingType and the innerText hash string is different from what my code created. 现在我还有其他问题,成功创建了Username和Password子级,但是Nonce子级在运行时被重写,这意味着Username和Password的创建方式与我编码的完全相同,但是Nonce继续创建时没有EncondingType并且innerText哈希字符串为与我的代码创建的代码不同。

EDIT 2 编辑2

I have done a simple test, by adding the following code 通过添加以下代码,我做了一个简单的测试

document.AppendChild(usernameTokenElement);

var xml = token.GetXml(document);

And if i inspect document i can see Nonce element with EncodingType attribute, but if i inspect xml it doesn't have EncodingType attribute on Nonce element. 如果我检查文档,我可以看到具有EncodingType属性的Nonce元素,但是如果我检查xml,则在Nonce元素上没有EncodingType属性。

EDIT 3 编辑3

Problem solved, but question of EDIT 2 not answered. 问题已解决,但EDIT 2的问题未解决。 In a nutshell Nonce is no longer required, the department responsible for managing this endpoint has done that configuration on server. 简而言之,不再需要Nonce,负责管理此终结点的部门已在服务器上完成了该配置。 In the specification of UsernameToken WSS document its written that Nonce and Created are not required, so by this assumption the problem was solved that way, remembering that this request is made on a https (SSL Tunneling). 在UsernameToken WSS 文档的规范中,其书面说明不需要Nonce和Created,因此通过这种假设可以解决此问题,同时请记住此请求是在https(SSL隧道)上进行的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM