Read .pfx file azure web app

Antonio Lopes 0 Reputation points
2024-08-15T20:14:39.3633333+00:00

Good afternoon,

I have an application that is hosted on azure web.app, in which I need to automatically register bank slips through a web.api, for this, I need to generate a token, and with each request pass the token in the header, locally the application works, but when it is published in a production environment, it does not work, below is the code detail:

private string GetAccessToken()

{

   try

   {

            var authUrl = _config["Boleto:Url_Auth"];

       var clientId = _config["Boleto:Client_Id"];

       string senhaPfx = _config["Boleto:SenhaCertPfx"]; 

       var clientSecret = clientId;

      

       string diretorioDoProjeto = AppDomain.CurrentDomain.BaseDirectory;

       // Concatena o caminho do diretório do projeto com o caminho relativo para a pasta "Reports"

       string caminhoDaPastaReports = Path.Combine(diretorioDoProjeto, "Certificado");

       // Concatena o caminho da pasta "Reports" com o nome do arquivo desejado

       string caminhoDoArquivo = Path.Combine(caminhoDaPastaReports, "certificado.pfx");



       // Carregar o certificado .pfx

       var certPath = Path.Combine(caminhoDoArquivo);

       var certificate = new X509Certificate2(certPath, senhaPfx);                     

       // Configurar as opções do RestClient para usar o certificado

       var options = new RestClientOptions($"authUrl ")

       {

           MaxTimeout = -1,

           ClientCertificates = new X509CertificateCollection { certificate }

       };

       // Criar o cliente e a requisição

       var client = new RestClient(options);

       var request = new RestRequest("", Method.Post);

       request.AddHeader("Content-Type", "application/x-www-form-urlencoded");

       request.AddParameter("grant_type", "client_credentials");

       request.AddParameter("client_id", clientId);

       request.AddParameter("scope", "boletos_inclusao boletos_consulta boletos_alteracao");

       // Executar a requisição

       RestResponse response = client.Execute(request);

       if (response.IsSuccessful)

       {

         

           dynamic result = JsonConvert.DeserializeObject(response.Content.ToString());

           // Retornar o token de acesso

           return result.access_token;

       }

       else

       {

           

           return null;

       }

   }

   catch (Exception ex)

   {

       var e = ex;

       throw;

   }

}

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,827 questions
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,545 questions
ASP.NET API
ASP.NET API
ASP.NET: A set of technologies in the .NET Framework for building web applications and XML web services.API: A software intermediary that allows two applications to interact with each other.
333 questions
Azure App Service
Azure App Service
Azure App Service is a service used to create and deploy scalable, mission-critical web apps.
7,725 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Konstantinos Passadis 19,081 Reputation points MVP
    2024-08-15T20:31:23.49+00:00

    Hello @Antonio lopes

    Welcome to Microsoft QnA!

    I am looking at this :

    string caminhoDoArquivo = Path.Combine(caminhoDaPastaReports, "certificado.pfx")
    

    this line assumes the certificate is located in a folder named "Certificado" within your project directory. However, the Azure production environment might have a different directory structure.

    You can check the file's presence using Directory.GetFiles in Azure to confirm it is in the expected location.

    https://learn.microsoft.com/en-us/rest/api/storageservices/list-directories-and-files

    IMPORTANT

    for the certificate store it in a location accessible by the application in Azure, Azure Key Vault.

    Use the WEBSITE_CONTENTSHARE environment variable to get the base path of your application directory in Azure.

    Example:

    string caminhoDaPastaReports = Path.Combine(Environment.GetEnvironmentVariable("WEBSITE_CONTENTSHARE"), "Certificado");

    ALSO

    Use application settings in Azure App Service to store production environment settings such as the authentication URL, client ID, and certificate password.

    Access application settings through the Azure portal and add the necessary settings.

    Use Key Vault to store secrets URLs , Certificates etc it is a best practice !!!

    https://learn.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates

    https://learn.microsoft.com/en-us/azure/app-service/reference-app-settings?tabs=kudu%2Cdotnet

    I used ChatGPT to produce a more solid code as an example :

    private string GetAccessToken()

    {

    try

    {

    var authUrl = _config["Boleto:Url_Auth"];

    var clientId = _config["Boleto:Client_Id"];

    string senhaPfx = _config["Boleto:SenhaCertPfx"];

    // Get the base path of the application directory in Azure

    string caminhoBase = Environment.GetEnvironmentVariable("WEBSITE_CONTENTSHARE");

    // Full path to the certificate

    string caminhoDoCertificado = Path.Combine(caminhoBase, "Certificado", "certificado.pfx");

    // Load the certificate

    var certificate = new X509Certificate2(caminhoDoCertificado, senhaPfx);

    // Configure HttpClient

    var handler = new HttpClientHandler();

    handler.ClientCertificates.Add(certificate);

    using (var client = new HttpClient(handler))

    {

    // Configure the request

    var requestContent = new FormUrlEncodedContent(new[]

    {

    new KeyValuePair<string, string>("grant_type", "client_credentials"),

    new KeyValuePair<string, string>("client_id", clientId),

    new KeyValuePair<string, string>("scope", "boletos_inclusao boletos_consulta boletos_alteracao")

    });

    // Make the request

    var response = await client.PostAsync(authUrl, requestContent);

    // Check the response

    if (response.IsSuccessStatusCode)

    {

    var content = await response.Content.ReadAsStringAsync();

    dynamic result = JsonConvert.DeserializeObject(content);

    return result.access_token;

    }

    else

    {

    // Handle error in response

    // Log the error or throw an exception

    return null;

    }

    }

    }

    catch (Exception ex)

    {

    // Handle exceptions

    // Log the exception or throw a more specific exception

    throw;

    }

    }

    Adjust the code and change the placeholders as well

    --

    The answer or portions of it may have been assisted by AI Source: ChatGPT Subscription

    I hope this helps!

    Kindly mark the answer as Accepted and Upvote in case it helped!

    Regards

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.