Consuming DGI (Efactura) WebServices
The provided services from DGI called Efactura
are webservices based on WS-Security. This specification is different
from the standards
Webservice generated by GeneXus, so in order to
communicate with them we must set up some configuration.
Note: These examples contains only an implementation for DGI Service "FACRECEPCIONSOBRE".
Efactura News
Prerequisites
- Certificate
- RUC Number
.NET
Note: GeneXus X Evolution 2 Upgrade 2 required
1. Install the certificate provided by DGI using mmc.exe from
Windows. Install it in "Personal" store on the Computer Account.
2. DGI signs the response with theirs certificate (DGI RUC PRUEBA
CEDE). So in order to work property,
DGI certificate must be installed
on the server.
In order to get this certificate go to https://www.efactura.dgi.gub.uy/ (Note2)
Install that certificate in Personal Store on computer account using
mmc.exe.
This certificate will be used in order to authenticate with DGI
web services.
3. Grant Certificate Permission to ASP.NET (or the user that is running the application): How to do it
4. Download and import this NET DGI XPZ WebService Sample that contains the
DGI WebService with the SDTs needed.
5. Set property Use Native Soap property = true to .NET Generator in order to use
WCF instead of GeneXus SOAP client. 6
6. Set the web.config as the following:
-
Replace: "RUC21XXXXXX" with the Serial Number of your certificate.
<system.serviceModel>
<client>
<endpoint address="https://efactura.dgi.gub.uy:6443/ePrueba/ws_eprueba"
binding="customBinding" bindingConfiguration="dgiBinding" contract="GeneXus.Programs.ISdtWS_eFactura"
name="GeneXus.Programs.SdtWS_eFacturaClient" behaviorConfiguration="ServiceBehavior">
<identity>
<dns value="DGI RUC PRUEBA CEDE" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="ServiceBehavior">
<clientCredentials>
<clientCertificate findValue="RUCXXXXXX" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" />
<defaultCertificate findValue="DGI RUC PRUEBA CEDE" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />
</serviceCertificate>
</clientCredentials>
<protectionLevel level="Sign" />
<!-- None, Sign, EncryptAndSign-->
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="dgiBinding">
<security includeTimestamp="false" allowSerializedSigningTokenOnReply="true"
authenticationMode="MutualCertificate" requireDerivedKeys="false" securityHeaderLayout="Lax"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<secureConversationBootstrap />
<localClientSettings detectReplays="false"/>
</security>
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport />
</binding>
</customBinding>
</bindings>
<extensions>
<behaviorExtensions>
<add name="protectionLevel" type="GeneXus.Wcf.ProtectionLevelBehaviorElement, GxClasses, Version=10.1.0.0,
Culture=neutral, PublicKeyToken=6f5bf81c27b6b8aa" />
</behaviorExtensions>
</extensions>
</system.serviceModel>
7. WebPanel "Ejemplo_ServicioSobre" contains an example for calling DGI Service "Envio de mensaje con Sobre".
You need to replace the certificate that is being used within code: &CryptoUtils.FindCertificate("RUC21XXXXXX")
If there is warning certificate message's, it get a "Certficate with Subject = RUC21XXXXX not found" error.
In order to fix, there are two options
- install a Certification Autorithy certificate (in order to fix the warning message) or
- Looking for invalid certificates, it means, setting
the parameter validonly = false . It would be replacing
&CryptoUtils.FindCertificate("RUC21XXXXXX") for
&CryptoUtils.FindCertificate1("RUC21XXXXXX", storeName,
storeLocation, false)
Note: DGI does not accept SOAP messages with empty element tags (example: <cantidad/>). XML Null Serialization property (SDT) property must be set to "No tag" in every SDT attribute.
Note2: Another way to Get the DGI certificate is from the SOAP header in the response:
<wsse:BinarySecurityToken >MIIFvjCC.............</wsse:BinarySecurityToken>.
Copy the text inside tags BinarySecurityToken, then save as "cert.cer".
JAVA (tested Apache Tomcat 6 and 7)
Note: GeneXus X Evolution 1 Upgrade 6 required
1. Download JAVA_DGI_WS.zip and extract to your hard drive.
2. DGIWS.xpz. Import into GeneXus.
3. Add "java_dgiWS_EOs.jar" to classpath in GeneXus.
3. Copy and merge all folders and files inside folder "webapp" to your Tomcat\WebApp directory.
4. Create your Java Key Store (JKS) from your Certificate:
For generating a .jks the following command can be executed:
keytool -v -importkeystore -srckeystore RUC2XXXXXXX.pfx -srcstoretype PKCS12 -destkeystore RUC2XXXXXXX.jks -deststoretype JKS. Refer to this link for more info.
(Temporary Limitation: Set the Java Key Store Password as the private key password).
In order to obtain certifcate alias (needed for the next step), run the following command:
keytool -list -v -keystore RUC2XXXXXXX.jks
5. Download the Server certificate and import it into the Java
cacerts. For example, suppose the downloaded certificate is
dgi_ssl_cert.cer, a sample command is:
keytool -import -alias dgi_efactura_https -file
"E:\DGI_HTTP_CERT.cer" -keystore "C:\Program
Files\Java\jre6\lib\security\cacerts" (default cacert
password: changeit)
Check this article for further information. By default the WebService address is https://efactura.dgi.gub.uy:6443/ePrueba/ws_eprueba, check the ServicioSobre WebPanel reference:
&DGIWSWrapper.Address = "https://efactura.dgi.gub.uy:6443/ePrueba/ws_eprueba"
6. Open "ServicioSobre" to see how the DGI WebService is being called.
You will need to edit the following code in order to specify the
certificate information:
Sub 'SetConfigurationOptions'
&keyStoreFile = "C:\\RUC2XXXXXXX.jks"
&keyStorePassword = "desarrollo" //Current Limitation: keystorepassword must be equal to private key password
&keyStoreType = "JKS"
&privateKeyAlias = "xx-xxxx-xx-xxx-xxxx-xxxxx"
//Setting Certificate information in order to sign XML
&xmlSignatureutil.keyStoreFile = &keyStoreFile
&xmlSignatureutil.keyStorePassword = &keyStorePassword
&xmlSignatureutil.keyStoreType = &keyStoreType
&xmlSignatureutil.privateKeyAlias = &privateKeyAlias
&xmlSignatureutil.privateKeyPassword = &keyStorePassword
//Setting Certificate information in order to sign the SOAP message
&DGIWSWrapper.keyStoreFile = &keyStoreFile
&DGIWSWrapper.keyStorePassword = &keyStorePassword
&DGIWSWrapper.keyStoreType = &keyStoreType
&DGIWSWrapper.privateKeyAlias = &privateKeyAlias
&DGIWSWrapper.privateKeyPassword = &keyStorePassword
Endsub
and make sure to change the RUCEmisor and associated information in the GenerateSDT subroutine.
Logging
By default, logging is placed in C:\Temp\log4j.log
Note: For production environment you should turn off logging by opening "java_dgiWS_EOs.jar" with Winrar and deleting "java_ log4j.properties".
Troubleshooting
Problem: ErrorDsc: "No se pudo inicializar el módulo
Axis Rampart -Connection has been shutdown:
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target"
Solution1: Check again the step 5, the server side
certificate is not imported in the local truststore
or not referenced
using the Java variables (javax.net.ssl.trustStorePassword and
javax.net.ssl.trustStore).
Solution2: Add the server certificate to the Java Runtime Environment used by the Application Server. Link |
No hay comentarios:
Publicar un comentario