Implementing fine-grained access control with ASP.NET Core custom endpoint metadata

Endpoint metadata are pieces of information associated with each endpoint in an ASP.NET Core application. An endpoint is essentially an entry point into your web application, such as an MVC controller action or a route in a minimal API, which can process HTTP requests. Endpoint metadata allow for the description of these endpoints’ characteristics and behaviors, such as authorization policies, CORS (Cross-Origin Resource Sharing) restrictions, filters, and more.

In the context of MVC controllers or API controllers, endpoint metadata are often defined using attributes, such as [Authorize], or [Produces]. With the introduction of minimal APIs in ASP.NET Core 6 and later versions, the concept of endpoint metadata has also been extended to these lighter and more flexible models. Endpoint metadata are typically added using fluent methods, such as RequireAuthorization() or RequireRateLimiting().

In this article, we will explore how to use your own endpoint metadata and consume them in an authorization policy to implement fine-grained access control in your ASP.NET Core application.

Continue reading “Implementing fine-grained access control with ASP.NET Core custom endpoint metadata”

Programmatically elevate a .NET application on any platform

There are times when your .NET program needs to perform an operation that requires administrative rights (elevated privileges). An example could be modifying the hosts file (C:\Windows\System32\drivers\etc\hosts on Windows or /etc/hosts on Linux and macOS).

Technically, it’s not possible to “elevate the current process”. In reality, the only thing we can do is to start a new process with administrative rights. In this article, we will explore how to do this with a console application – while obtaining the user’s consent – on any platform.

Continue reading “Programmatically elevate a .NET application on any platform”

Best practices for integrating the Azure Storage SDK into your .NET applications

I have often had to integrate the Azure Storage SDK into various applications, and each time, I’ve done it differently. Here’s an overview of the questions I’ve asked myself over time:

Should I register a BlobServiceClient instance in the dependency injection service? What if I need to use multiple storage accounts? How do I manage multiple clients for different resources, such as containers, tables, or individual queues? Should I create my own abstraction or factory on top of the SDK?

How do I configure the clients? Should I create my own option classes? How can I easily override the SDK options? What if I want to use the Azurite emulator locally, and a managed identity in the Azure cloud environment?

I realized that I often created instances of DefaultAzureCredential throughout my code, for different services such as Azure Storage, Event Grid, Key Vault, etc. DefaultAzureCredential can slow down application startup in a local environment. How can I avoid the multiplication of these TokenCredential derived instances?

If you’ve ever asked yourself these questions, then this article is for you. Just like for dependency injection, configuration, logging, and HTTP request resilience, Microsoft provides a library of extensions to uniformly integrate the Azure SDK into your applications.

Unsurprisingly, the name of this library is Microsoft.Extensions.Azure. In the remainder of this article, we will use it to integrate the Azure Blob Storage SDK, but similar code applies to other Azure services.

Continue reading “Best practices for integrating the Azure Storage SDK into your .NET applications”

Evolutive and robust password hashing using PBKDF2 in .NET

PBKDF2 (Password-Based Key Derivation Function) is a key derivation function that is often used for password hashing. Password managers such as 1Password and Bitwarden rely on it. This is also how ASP.NET Core Identity stores user passwords.

It’s easy to use improper parameters when using PBKDF2. Many .NET developers get inspired by articles written several years ago which are no longer up-to-date with the current security standards. I am writing this article in part to address this issue. I will provide references and recommendations from the Open Worldwide Application Security Project (OWASP) and the National Institute of Standards and Technology (NIST). This way, you will be able to adapt the code to the recommendations of recognized security organizations, even in the years to come.

The C# code you will see is partly inspired by ASP.NET Core Identity’s source code. If you are not familiar with the PBKDF2 algorithm, you will find explanations in the following section. The code will be evolutive. By this I mean that you will be able to easily change the PBKDF2 parameters and maintain the ability to rehash the passwords already stored in your databases with the new parameters. Furthermore, it will be optimized to reduce memory allocation using .NET APIs based on Span<T>.

I am not a security specialist, so my vocabulary should be accessible to most. Let’s begin with an introduction to PBKDF2. If you wish to skip to the final code, here it is.

Continue reading “Evolutive and robust password hashing using PBKDF2 in .NET”

Optimizing .NET solution architecture for faster compilation through project decoupling

In the previous article, we discussed how to identify Roslyn analyzers that have a negative impact on the compilation time of a .NET solution. For some projects, this can represent a significant percentage of the compilation time, which can affect developer productivity and satisfaction, as well as metrics related to performance and releases.

In this next part, we’ll further explore the possibilities for optimizing the compilation of a .NET solution by focusing on the solution’s architecture and the dependencies between projects. We’ll examine a common architecture of projects within a .NET solution and attempt to apply inversion of control, a concept that is normally familiar to developers but on a different scale.

Continue reading “Optimizing .NET solution architecture for faster compilation through project decoupling”