Showing posts with label .net core. Show all posts
Showing posts with label .net core. Show all posts

Saturday, 28 December 2024

How to use User-secret to protect secrets in dotnet application.

 

 Using user secrets in a .NET Web API project to securely manage your database password is an excellent practice. It keeps sensitive information like database passwords out of your source code and version control system.  

    Questions about managing secrets and securely handling sensitive data in .NET applications are quite common in job interviews, especially for roles that require knowledge of security best practices. Understanding how to securely manage and deploy secrets demonstrates your ability to maintain the security and integrity of an application.

Why Secrets Management is Important:

  • Protects sensitive information like API keys, database passwords, and other confidential data.

  • Prevents unauthorized access and potential data breaches.

  • Protects from uploading such sensitive information in code repository.

User Secrets in Development:

  • Use Microsoft.Extensions.Configuration.UserSecrets to store secrets securely during development.

  • Initialize user secrets in your project: 

 dotnet user-secrets init --project [projectName]

  •  Set secrets using the CLI:
     
  • dotnet user-secrets --project [projectName]
      set "ConnectionStrings:DefaultConnection:Password" "YourDatabasePassword"
Accessing Secrets in Code:
  • Load user secrets in your Program.cs or Startup.cs.
    var builder = WebApplication.CreateBuilder(args);
    builder.Configuration.AddUserSecrets<Program>();


Example appsettings.json:
{
    "ConnectionStrings": {
      "DefaultConnection": "Server=your_server;Database=your_database;User Id=your_userid;TrustServerCertificate=True;MultipleActiveResultSets=true;"
    }
  }
Program.cs or startup.cs
var builder = WebApplication.CreateBuilder(args);

// Load User Secrets
builder.Configuration.AddUserSecrets<Program>();

// Build the connection string
var defaultConnectionString = builder.Configuration.GetConnectionString("DefaultConnection");
var dbPassword = builder.Configuration["ConnectionStrings:DefaultConnection:Password"];
var connectionString = $"{defaultConnectionString}Password={dbPassword};";

// Add services to the container.
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));

var app = builder.Build();

Best Practices for Production:
  • Use environment variables or a secret management service (e.g., Azure Key Vault, AWS Secrets Manager) to store and retrieve secrets in production.
  • Configure your application to load secrets from the chosen service:
        
builder.Configuration.AddEnvironmentVariables();
// Or use Azure Key Vault
builder.Configuration.AddAzureKeyVault(
    new Uri("https://your-keyvault-name.vault.azure.net/"),
new DefaultAzureCredential());

Automating Secret Management:
  • Integrate secret management into CI/CD pipelines to automate the secure deployment of secrets.
  • Use tools like Azure DevOps, GitHub Actions, or Jenkins to manage secrets during deployment.

    Example Scenario:

    Question: How would you securely manage and deploy secrets in a .NET Web API application?
    Answer: "In a .NET Web API application, I would use Microsoft.Extensions.Configuration.UserSecrets to manage secrets during development. This helps keep sensitive information like database passwords secure and out of source control. For production environments, I would leverage a secret management service like Azure Key Vault to store and retrieve secrets securely. This ensures that secrets are managed centrally and securely accessed by the application. Additionally, I would integrate secret management into CI/CD pipelines to automate the secure deployment of secrets, ensuring that sensitive information remains protected throughout the development and deployment process."

Saturday, 11 September 2021

simple use of Record in c#9 and newer versions

 c# 9 introduces a new keyword Record which makes an object immutable. Properties in the record can be initialised at the time of creation or constructor call only. Record can be written like how we write a class. It has same syntax as class.

For example:

public record Friend

        {

            public Friend()

            {

            }

            public Friend(string name, string surname)

            {

                this.Name = name;

                this.Surname = surname;

            }

            public string Name { get; init; }

            public string Surname { get; init; }

        }

use of Friend record:

var newFriend = new Friend("Tom", "Pandey");

//--Note: we called here using constructor.

var newFriend1 = new Friend{Name="Tom",Surname= "Pandey"};

//Note: this calls the constructor without parameter. constructor without parameter is not required to to call to initiate the record. 

This record is equivalent to below code which don't have a constructor:

public record Friend

        {

            public string Name { get; init; }

            public string Surname { get; init; }

        }


use of Friend Record:

var newFriend = new Friend("Tom", "Pandey");

Note: we called here using constructor, but we don't have constructor defined. so It will throw an error. Instead we create object friend like this:

var newFriend1 = new Friend{Name="Tom",Surname= "Pandey"};

In both the example of Record, we can not modify the property Name or Surname after the object is created. 

The Friend record with constructor can be written as below code in one line:

public record Friend(String Name, String Surname);

use of Friend Record: 

Friend friend = new Friend("John","Pandey" );

Note: since this is constructor type record, we must create record object using constructor.for example below code will throw error:

var newFriend1 = new Friend{Name="Tom",Surname= "Pandey"};

On compilation, this is converted to class with immutable properties.

Thursday, 11 February 2021

How to Enable Cors in .net standard API ( or .net core API) for PUT GET and DELETE Methods

 Error:

Access to fetch at 'https://localhost:44340/api/employee' from origin 'https://localhost:44339' has been blocked by CORS policy: Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.


:44340/api/employee:1 Failed to load resource: net::ERR_FAILED


blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]


      Unhandled exception rendering component: TypeError: Failed to fetch


WebAssembly.JSException: TypeError: Failed to fetch


  at System.Net.Http.WebAssemblyHttpHandler.doFetch (System.Threading.Tasks.TaskCompletionSource`1[TResult] tcs, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x2fcb610 + 0x00a30> in <filename unknown>:0 


  at System.Net.Http.WebAssemblyHttpHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x2f9dd40 + 0x00174> in <filename unknown>:0 


  at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x2f98030 + 0x00160> in <filename unknown>:0 


  at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) <0x2f71090 + 0x00182> in <filename unknown>:0 


  at System.Net.Http.HttpClient.FinishSendAsyncBuffered (System.Threading.Tasks.Task`1[TResult] sendTask, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationTokenSource cts, System.Boolean disposeCts) <0x3394518 + 0x00278> in <filename unknown>:0 


  at sanjeebblazorapp.App.Services.EmployeeDataService.UpdateEmployee (sanjeebblazorapp.Shared.Employee employee) [0x00051] in C:\Users\sanje\source\repos\sanjeebko\sanjeebtutorial-blazor\sanjeebblazorapp.App\sanjeebblazorapp.App\Services\EmployeeDataService.cs:42 


  at sanjeebblazorapp.App.Pages.EmployeeEdit.HandleValidSubmit () [0x001b0] in C:\Users\sanje\source\repos\sanjeebko\sanjeebtutorial-blazor\sanjeebblazorapp.App\sanjeebblazorapp.App\Pages\EmployeeEdit.cs:81 


  at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion (System.Threading.Tasks.Task task) <0x3395450 + 0x000da> in <filename unknown>:0 


  at Microsoft.AspNetCore.Components.Forms.EditForm.HandleSubmitAsync () <0x3307b00 + 0x00218> in <filename unknown>:0 


  at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion (System.Threading.Tasks.Task task) <0x3395450 + 0x000da> in <filename unknown>:0 


  at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask (System.Threading.Tasks.Task taskToHandle) <0x2fb1590 + 0x000b6> in <filename unknown>:0 

Solution:

TO enable cors in .net core web API, cors policy need to be added in the services. Below code in blue color needs to be added in the Startup.cs file

public void ConfigureServices(IServiceCollection services)

        {

            

            services.AddDbContext<AppDbContext>(options =>

                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

   

            services.AddCors(options =>

            {

                options.AddPolicy("Open", builder => builder.AllowAnyOrigin().AllowAnyHeader().WithMethods("PUT","DELETE","GET"));

            });


            services.AddControllers(); 

        }


 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

        {

            if (env.IsDevelopment())

            {

                app.UseDeveloperExceptionPage();

            }


            app.UseHttpsRedirection();


            app.UseRouting();


            app.UseAuthorization();


            app.UseCors("Open");


            app.UseEndpoints(endpoints =>

            {

                endpoints.MapControllers();

            });

        }

How to use User-secret to protect secrets in dotnet application.

    Using user secrets in a .NET Web API project to securely manage your database password is an excellent practice. It keeps sensitive info...