我是消费新手webservices
,我必须将文件发送到 Web 服务并接收响应,我的问题是我无法生成SOAP Header
有效的。
要使用的 Web 服务是这样的:
https://facturaelectronica.dian.gov.co/habilitacion/B2BIntegrationEngine/FacturaElectronica/facturaElectronica.wsdl
文档中的规范是标题应如下所示:
使用 Base64 的请求示例
POST /B2BIntegrationEngine/FacturaElectronica HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
Content-Length: 3342
Host: 192.168.250.65:9080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rep="http://www.dian.gov.co/servicios/facturaelectronica/ReportarFactura">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>8ac82326-3016-430f-8d69-9efc4bcefd8f</wsse:Username>
<wsse:Password>6361b7b5322acb07ced00a35a85a4cc5183da3a42ede0b07f578067a18425a55</wsse:Password>
<wsse:NonceEncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">FmbZRkx1jh2A+imgjD2fLQ==</wsse:Nonce>
<wsu:Created>2015-10-06T12:00:33.762Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
但尽我所能,我唯一能得到的是:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="uuid-c635f931-8274-4d3d-82a1-460a2f04af73-1">
<o:Username>22ffb485-64bc-4619-8a63-340de2dd7eec</o:Username>
<o:Password>+eho+ADhrJkwZtKGabXIZOEX/0YVa206TmKnQSwt+qE=</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
这就是我正在做的事情:
const string apiUrl = "https://facturaelectronica.dian.gov.co/habilitacion/B2BIntegrationEngine/FacturaElectronica",
apiUserName = "8ac82326-3016-430f-8d69-9efc4bcefd8f";
string apiPassword = "6361b7b5322acb07ced00a35a85a4cc5183da3a42ede0b07f578067a18425a55";
EndpointAddress endpointAddress = new EndpointAddress(new Uri(apiUrl));
SecurityBindingElement securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
securityElement.AllowInsecureTransport = false;
securityElement.EnableUnsecuredResponse = true;
securityElement.IncludeTimestamp = false;
TextMessageEncodingBindingElement encodingElement = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
HttpsTransportBindingElement transportElement = new HttpsTransportBindingElement();
CustomBinding binding = new CustomBinding(securityElement, encodingElement, transportElement);
//basic prueba
BasicHttpSecurityMode securityMode = new BasicHttpSecurityMode();
BasicHttpBinding binding2 = new BasicHttpBinding(securityMode);
// Then assign username and password based on the proxy. For example -
//var remoteAddress = new EndpointAddress("");
WSDian.facturaElectronicaPortNameClient service = new WSDian.facturaElectronicaPortNameClient(binding, endpointAddress);
//WSDian.facturaElectronicaPortNameClient service = new WSDian.facturaElectronicaPortNameClient(binding2, endpointAddress);
service.ClientCredentials.UserName.UserName = apiUserName;
service.ClientCredentials.UserName.Password = apiPassword;
var Obtnonce = GetNonce();
byte[] archivo = FileToByteArray(@"c:\temp\ws_f0816002834000000000A.zip");
service.Open();
WSDian.EnvioFacturaElectronica enviofactura = new WSDian.EnvioFacturaElectronica();
enviofactura.NIT = "816002834";
enviofactura.InvoiceNumber = "10";
enviofactura.IssueDate = Convert.ToDateTime("2018-01-01 05:00:00");
enviofactura.Document = archivo;
//temporal
WSDian.EnvioFacturaElectronicaPeticion envioFacturaElectronicaPeticion = new WSDian.EnvioFacturaElectronicaPeticion();
WSDian.EnvioFacturaElectronicaRespuesta envioFacturaElectronicaRespuesta = new WSDian.EnvioFacturaElectronicaRespuesta();
WSDian.AcuseRecibo acuseRecibo = new WSDian.AcuseRecibo();
WSDian.ReceivedInvoice receivedInvoice = new WSDian.ReceivedInvoice();
WSDian.facturaElectronicaPortNameClient facturaElectronicaPortNameClient = new WSDian.facturaElectronicaPortNameClient();
envioFacturaElectronicaPeticion.EnvioFacturaElectronicaPeticion1 = enviofactura;
var versionSoap = acuseRecibo.GetType();
acuseRecibo = service.EnvioFacturaElectronica(envioFacturaElectronicaPeticion.EnvioFacturaElectronicaPeticion1);
但我收到错误:
无法对安全令牌进行身份验证或授权;嵌套异常是 org.apache.ws.security.WSSecurityException:无法对安全令牌进行身份验证或授权
我不明白如何按要求生成 SOAP 标头,我不应该wsdl
自动生成吗?
谢谢你的帮助。
我补充说,这是我的Web.config
?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net" >
<listeners>
<add name="MyTraceFile"/>
<add name="MyConsole"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add
name="MyTraceFile"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="System.Net.trace.log" />
<add name="MyConsole" type="System.Diagnostics.ConsoleTraceListener" />
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
</switches>
</system.diagnostics>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6" />
<httpRuntime targetFramework="4.6"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="facturaElectronicaPortNameSoap11">
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://facturaelectronica.dian.gov.co:80/habilitacion/B2BIntegrationEngine/FacturaElectronica"
binding="basicHttpBinding" bindingConfiguration="facturaElectronicaPortNameSoap11"
contract="WSDian.facturaElectronicaPortName" name="facturaElectronicaPortNameSoap11" />
</client>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- Para evitar revelar información de los metadatos, establezca los valores siguientes en false antes de la implementación -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- Para recibir detalles de las excepciones en los fallos, con el fin de poder realizar la depuración, establezca el valor siguiente en true. Para no revelar información sobre las excepciones, establézcalo en false antes de la implementación -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
Para examinar el directorio raíz de la aplicación web durante la depuración, establezca el valor siguiente en true.
Establézcalo en false antes de la implementación para evitar revelar información sobre la carpeta de aplicación web.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
更新:
我成功地对其进行了测试,SoapUI
我意识到:
- 用户很好,是DIAN提供的软件的唯一标识
- 密码是使用
SHA-256
DIAN 站点上配置的密码的结果。
现在,最大的问题是生成<soapenv:Header>
一个<wsse:UsernameToken>
包含<wsse:Nonce>
y<wsu:Created>
更新
经过大量搜索,我找到了这篇文章,我设法接近了一代<soapenv:Header>
:
https://weblog.west-wind.com/posts/2012/Nov/24/WCF-WSSecurity-and-WSE-Nonce-Authentication
现在我的 Header 看起来像这样:
<s:Envelope xmln s:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken><wsse:Username><!--Removed--></wsse:Username>
<wsse:Password><!--Removed--></wsse:Password>
<wsse: Nonce>t21C05VjRqomc+OehZoSzwqhmaM=</wsse:Nonce>
<wsse:Created>2018-08-28T08:03:40.749Z</wsse:Created>
</wsse:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<EnvioFacturaElectronicaPeticion xmlns="http://www.dian.gov.co/servicios/facturaelectronica/ReportarFactura">
<NIT><!--Removed--></NIT>
<InvoiceNumber>980000000</InvoiceNumber>
<IssueDate>2018-08-28T19:00:00</IssueDate>
<Document>UEsDBBQAAAAIAPBkHE3djKx2hwgAAEcdAAAeAAAAZmFjZV9mMDgxNjAwMjgzNDAwM0E2OTl.........
现在我的问题是它会产生以下错误:
System.Net 信息:0:[11736] Connection#33583636 - 收到状态行:版本 = 1.1,状态代码 = 400,状态描述 = 错误请求。
System.Net 错误:0:[11736] HttpWebRequest#36620214::GetResponse 异常 - 远程服务器错误:(400)错误请求..
有任何想法吗?
最后我设法连接到服务
DIAN
并获得成功的响应:我找到:
SHA-256
nonce
要发送的类是这样的:
也可以使用
MTOM
DIAN 推荐的方式发送,在这种情况下,类如下所示:我
web.config
是这样的:最后:
WCF
使用中创建它C#
NuGet
Microsoft.Web.Services3包Referencia de servicio
( https://facturaelectronica.dian.gov.co/habilitacion/B2BIntegrationEngine/FacturaElectronica/facturaElectronica.wsdl )https
,必须手动进行更改,因为在添加对服务的引用时,它会将其作为http
。就是这样。
剩下的就是处理我公开的两种方法中的任何一种都没有实现的服务响应。但这回答了我提出的问题。
我希望这些信息对你有用。
我面临同样的问题,我分享我到目前为止找到的信息
根据WSS标准,
password
计算如下:在您公开的代码中,虽然您指定了 line
var Obtnonce = GetNonce();
,但不清楚您是否使用nonce
和timestamp
来计算password_digest
.现在,根据 DIAN 的技术附件,必须发送sha256
( password )
,它没有指定如何使用nonce
和timestamp
,实际上在另一个暴露被调用 DIAN 的 Web 服务中,Consulta_del_Resultado_de_Transacciones
它不需要发送nonce
和createdtime
,因为那部分不清楚,您应该尝试不同的变体。我的建议是更改代码以计算
password
考虑nonce
和timestamp
:考虑
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest" o Type="...#PasswordText"
根据您发送password
申请的方式指定属性base64
。如果我发现其他东西,我仍在研究这个主题,我会在这里发布,如果你解决它,如果你发布它,我将不胜感激。