private async Task <string> GetLoginTicketResponse(string base64SignedCms) { string loginTicketResponse; try { _logger.LogInformation("Call WSAA URL: {url}", IsProduction ? ProductionEnvironment : TestingEnvironment); var wsaaService = new AfipLoginCmsServiceReference.LoginCMSClient(); wsaaService.Endpoint.Address = new EndpointAddress(IsProduction ? ProductionEnvironment : TestingEnvironment); var response = await wsaaService.loginCmsAsync(base64SignedCms); loginTicketResponse = response.loginCmsReturn; _logger.LogInformation("loginCmsAsync response: {loginResponse}", loginTicketResponse); } catch (Exception ex) { _logger.LogError("GetLoginTicketResponse Error: {error}", ex.Message); throw new Exception($"GetLoginTicketResponse Error: {ex.Message}"); } return(loginTicketResponse); }
private static uint GlobalUniqueID = 0; // OJO! NO ES THREAD-SAFE /// <summary> /// Construye un Login Ticket obtenido del WSAA /// </summary> /// <param name="service">Servicio al que se desea acceder</param> /// <param name="urlWsaa">URL del WSAA</param> /// <param name="x509CertificateFilePath">Ruta del certificado X509 (con clave privada) usado para firmar</param> /// <param name="password">Password del certificado X509 (con clave privada) usado para firmar</param> /// <param name="verbose">Nivel detallado de descripcion? true/false</param> /// <remarks></remarks> public async Task <WsaaTicket> LoginCmsAsync(string service, string x509CertificateFilePath, string password, bool verbose) { var ticketCacheFile = string.IsNullOrEmpty(TicketCacheFolderPath) ? service + "ticket.json" : TicketCacheFolderPath + service + "ticket.json"; if (File.Exists(ticketCacheFile)) { var ticketJson = File.ReadAllText(ticketCacheFile); var ticket = JsonConvert.DeserializeObject <WsaaTicket>(ticketJson); if (DateTime.UtcNow <= ticket.ExpirationTime) { return(ticket); } } const string ID_FNC = "[ObtenerLoginTicketResponse]"; CertificatePath = x509CertificateFilePath; VerboseMode = verbose; X509CertificateManager.VerboseMode = verbose; // PASO 1: Genero el Login Ticket Request try { GlobalUniqueID += 1; XmlLoginTicketRequest = new XmlDocument(); XmlLoginTicketRequest.LoadXml(XmlStrLoginTicketRequestTemplate); var xmlNodoUniqueId = XmlLoginTicketRequest.SelectSingleNode("//uniqueId"); var xmlNodoGenerationTime = XmlLoginTicketRequest.SelectSingleNode("//generationTime"); var xmlNodoExpirationTime = XmlLoginTicketRequest.SelectSingleNode("//expirationTime"); var xmlNodoService = XmlLoginTicketRequest.SelectSingleNode("//service"); xmlNodoGenerationTime.InnerText = DateTime.Now.AddMinutes(-10).ToString("s"); xmlNodoExpirationTime.InnerText = DateTime.Now.AddMinutes(+10).ToString("s"); xmlNodoUniqueId.InnerText = Convert.ToString(GlobalUniqueID); xmlNodoService.InnerText = service; Service = service; if (VerboseMode) { Console.WriteLine(XmlLoginTicketRequest.OuterXml); } } catch (Exception ex) { throw new Exception(ID_FNC + "***Error GENERANDO el LoginTicketRequest : " + ex.Message + ex.StackTrace); } string base64SignedCms; // PASO 2: Firmo el Login Ticket Request try { if (VerboseMode) { Console.WriteLine(ID_FNC + "***Leyendo certificado: {0}", CertificatePath); } var securePassword = new NetworkCredential("", password).SecurePassword; securePassword.MakeReadOnly(); var certFirmante = X509CertificateManager.GetCertificateFromFile(CertificatePath, securePassword); if (VerboseMode) { Console.WriteLine(ID_FNC + "***Firmando: "); Console.WriteLine(XmlLoginTicketRequest.OuterXml); } // Convierto el Login Ticket Request a bytes, firmo el msg y lo convierto a Base64 var msgEncoding = Encoding.UTF8; var msgBytes = msgEncoding.GetBytes(XmlLoginTicketRequest.OuterXml); var encodedSignedCms = X509CertificateManager.SignMessageBytes(msgBytes, certFirmante); base64SignedCms = Convert.ToBase64String(encodedSignedCms); } catch (Exception ex) { throw new Exception(ID_FNC + "***Error FIRMANDO el LoginTicketRequest : " + ex.Message); } string loginTicketResponse; // PASO 3: Invoco al WSAA para obtener el Login Ticket Response try { if (VerboseMode) { Console.WriteLine(ID_FNC + "***Llamando al WSAA en URL: {0}", IsProdEnvironment ? WsaaUrlProd : WsaaUrlHomologation); Console.WriteLine(ID_FNC + "***Argumento en el request:"); Console.WriteLine(base64SignedCms); } var wsaaService = new AfipLoginCmsServiceReference.LoginCMSClient(); wsaaService.Endpoint.Address = new EndpointAddress(IsProdEnvironment ? WsaaUrlProd : WsaaUrlHomologation); var response = await wsaaService.loginCmsAsync(base64SignedCms); loginTicketResponse = response.loginCmsReturn; if (VerboseMode) { Console.WriteLine(ID_FNC + "***LoguinTicketResponse: "); Console.WriteLine(loginTicketResponse); } } catch (Exception ex) { throw new Exception(ID_FNC + "***Error INVOCANDO al servicio WSAA : " + ex.Message); } // PASO 4: Analizo el Login Ticket Response recibido del WSAA try { XmlLoginTicketResponse = new XmlDocument(); XmlLoginTicketResponse.LoadXml(loginTicketResponse); UniqueId = uint.Parse(XmlLoginTicketResponse.SelectSingleNode("//uniqueId").InnerText); GenerationTime = DateTime.Parse(XmlLoginTicketResponse.SelectSingleNode("//generationTime").InnerText); ExpirationTime = DateTime.Parse(XmlLoginTicketResponse.SelectSingleNode("//expirationTime").InnerText); Sign = XmlLoginTicketResponse.SelectSingleNode("//sign").InnerText; Token = XmlLoginTicketResponse.SelectSingleNode("//token").InnerText; } catch (Exception ex) { throw new Exception(ID_FNC + "***Error ANALIZANDO el LoginTicketResponse : " + ex.Message); } var ticketResponse = new WsaaTicket { Sign = Sign, Token = Token, ExpirationTime = ExpirationTime }; File.WriteAllText(ticketCacheFile, JsonConvert.SerializeObject(ticketResponse)); return(ticketResponse); }