
Hace 5 Horas
|
|
Miembro
|
|
Registrado: jul 2017
Posts: 168
Reputación: 10
|
|
Cita:
Empezado por sglorka
Perfecto, ¿Usas "Agregar referencia web" o "Agregar referencia de servicio"? contra https://webservice.face.gob.es/facturasspp?wsdl
¿La clase cliente hereda de ClientBase<T> o de SoapHttpClientProtocol?
Te agradecería que me aclarases esta información
Gracias de antemano
Saludos
|
Agregar referencia de servicio. y haber yo a facturae como tal no probé, intente ir a obtener los DIR3 pero me daba error 400. No se si pille cuando estaban cambiando toda la movida, hice muchas pruebas y lo deje. Te dejo un código haber si sacas algo de esto. Lo del toquen nunca había hecho así que no se si estará bien.
Cita:
private readonly string _url = "https://ws.face.gob.es/organismos/v1/directorio";
public async Task<ConsultarUnidadesResponse> ObtenerDirectorioAsync()
{
// 1. Configuración de Seguridad de Red
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
// System.Net.ServicePointManager.Expect100Continue = false;
// 2. Obtener Certificado
X509Certificate2 certificado = null;
try
{
// NOTA: BDCertificados debe devolver el cert cargado con X509KeyStorageFlags.MachineKeySet
(certificado, _) = BDCertificados.ObtenerCertificado("persona");
if (certificado == null) throw new Exception("Certificado no encontrado.");
}
catch (Exception ex) { throw new Exception("Error al cargar certificado: " + ex.Message); }
// 3. Configuración del Binding
var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
// binding.MaxReceivedMessageSize = 2147483647;
// binding.AllowCookies = true;
var endpoint = new EndpointAddress(_url);
using (var client = new organismosv1directorioPortClient(binding, endpoint))
{
client.ClientCredentials.ClientCertificate.Certificate = certificado;
// 4. Generar el Token JWT firmado
string tokenJwt = GenerarTokenJWT(certificado);
// 5. Ámbito de la operación para inyectar la cabecera
using (new OperationContextScope(client.InnerChannel))
{
var property = new HttpRequestMessageProperty();
// El "Bearer" es lo que exige el API v2.0.0
property.Headers["Authorization"] = "Bearer " + tokenJwt;
property.Headers["Content-Type"] = "text/xml; charset=utf-8";
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = property;
try
{
// 6. Request Mínimo (Evitar enviar campos vacíos que causan error 400)
var request = new ConsultarUnidadesRequest
{
codigo = "L01234567",
estado = "V", // Solo vigentes
nombre = "",
identificador = "",
padre = "",
administracion = ""
};
return await client.consultarUnidadesAsync(request);
}
catch (Exception ex)
{
string msg = ex.InnerException != null ? ex.InnerException.Message : ex.Message;
throw new Exception("Error 400 en FACe: " + msg);
}
}
}
}
// --- GENERADOR DE TOKEN JWT (Basado en Manual FACe pág. 86) ---
private string GenerarTokenJWT(X509Certificate2 cert)
{
// Header: RS256 + Certificado en x5c
string certBase64 = Convert.ToBase64String(cert.RawData);
string headerJson = "{\"alg\":\"RS256\",\"typ\":\"JWT\",\"x5c\":[\"" + certBase64 + "\"]}";
// Payload: exp y iat (sin decimales)
long iat = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
long exp = iat + 7200;
string payloadJson = "{\"exp\":" + exp + ",\"iat\":" + iat + "}";
// Codificación Base64Url
string headerEnc = Base64UrlEncode(Encoding.UTF8.GetBytes(headerJson));
string payloadEnc = Base64UrlEncode(Encoding.UTF8.GetBytes(payloadJson));
string dataToSign = headerEnc + "." + payloadEnc;
// Firma con SHA256 (Compatible con .NET 4.8 y claves CNG/CAPI)
byte[] signatureBytes;
using (RSA rsa = cert.GetRSAPrivateKey())
{
if (rsa == null) throw new Exception("El certificado no tiene clave privada RSA accesible.");
signatureBytes = rsa.SignData(Encoding.UTF8.GetBytes(dataToSign), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
return dataToSign + "." + Base64UrlEncode(signatureBytes);
}
private string Base64UrlEncode(byte[] input)
{
return Convert.ToBase64String(input)
.Replace("+", "-")
.Replace("/", "_")
.Replace("=", "");
}
|
|