Showing posts with label DotNet/dotnetCore. Show all posts
Showing posts with label DotNet/dotnetCore. Show all posts

API Key Authentication in ASP.NET Core Web API

 In this tutorial, we will learn how to use API Key authentication to secure ASP.NET Core Web API in 2 different ways: 

  • Custom Attribute 
  • Custom Middleware.

Keep in mind that using API Key Authentication should be limited to the service clients or well-known clients, in other words, it is not recommended that you use the API Key Authentication to actually authenticate your users, it is mainly used to identify and authorize a project or service that is connecting to your APIs. So it will keep a secure link between your APIs and the client of your APIs 

Lets Open Visual Studio 2022 and create a new project and choose ASP.NET Core Web Application template.





Now give a project name like ‘SecuringWebApiUsingApiKey’ and then press Next:



Now select the .NET Framework 6.0 and click next

After clicking on Next,you will see below the Project structure



Now run the application, and you will see the below output in the browser



There are many ways to implement the API Key Authentication, in this tutorial we will see  2 ways.

1. API Key Authentication Using Custom Attributes

Now we will create a new custom attribute which will be inherited from ASP.NET Core Attributes and it will create the IAsyncActionResult interface

We will verify that the ApiKey header exists, has a value and its value is actually the correct API Key, unless otherwise, we will return a 401 Unauthorized response to the client indicating that the request is not authorized to access the endpoint.

So now let's add an Attribute:

Right-click on your project and choose to add New Folder

Give it a name, like CustomeAttributes

then right-click on the Attributes folder, and choose to add then New item …

Let’s name the Attribute as ApiKeyAuthAttribute.

Now you should have a new class under the Attributes folder as below:



We will be using this attribute to decorate the controller so that any request that is routed to the attributed controller will be redirected to ApiKeyAuthAttribute

Your custom attribute will be inherited from the base abstract class Attribute of Global System. Attribute, which will transform your class into a custom attribute,

And also you will be implementing the IAsyncActionFilter Interface so that your custom attribute will be able to intercept the call request, process it, and then route the request back to the controller.

Now let’s see what we will do in this custom attribute:

using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;

namespace APIKeyAuthentication.CustomeAttributes
{
    [AttributeUsage(validOn: AttributeTargets.Class)]
    public class ApiKeyAuthAttribute : Attribute, IAsyncActionFilter
    {
        private const string apiKeyName = "ApiKey";
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            if (!context.HttpContext.Request.Headers.TryGetValue(apiKeyName, out var extractedApiKey))
            {
                context.Result = new ContentResult()
                {
                    StatusCode = 401,
                    Content = "Api Key is not Given"
                };
                return;
            }
            var appSettings = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();
            var key = appSettings.GetValue<string>(apiKeyName);
            if (!key.Equals(extractedApiKey))
            {
                context.Result = new ContentResult()
                {
                    StatusCode = 401,
                    Content = "Api Key is not valid"
                };
                return;
            }
            await next();
        }
    }
}

so let me explain what we are doing:

[AttributeUsage(validOn: AttributeTargets.Class)]

this decoration is also an Attribute that indicates and specifies where the ApiKeyAuthAttribute will be used, in our case we have specified that ApiKeyAuthAttribute will only be used on classes, like Controllers.

The AttributeTargets is an enum that applies flags, so you can use the pipe | operator (bitwise or) to specify more usages for your custom attribute, so the below would indicate the ApiKeyAuthAttribute can be used on both classes and/or methods (Controller and/or action method)

[AttributeUsage(validOn: AttributeTargets.Class | AttributeTargets.Method)]

Ok, so now allow me to explain the first logical section of the code:

if (!context.HttpContext.Request.Headers.TryGetValue(apiKeyName, out var extractedApiKey))
{ context.Result = new ContentResult() { StatusCode = 401, Content = "Api Key not Given" }; return; }
In the above code, we are first checking the request headers collection object if it has a key with the name ApiKey. Of course, you can use whatever header name you like.

Now if the header doesn’t include the ApiKey as a key, then we will return a 401 Unauthorized response code with a message indicating that the API Key was not provided.

You can leave the Content field empty or just simply return UnauthorizedResult instead of ContentResult without having to specify the StatusCode and the Content and that will just return 401 without any message.

If the ApiKey header was sent, we will then move to the next step which is validating that the value of the ApiKey header matches the ApiKey defined in our API project.

Now, let’s go and create an API Key. For the sake of this tutorial, we will be adding the API Key inside the appsettings.json file, which is the settings file that resides in your ASP.NET Core Web API Project.

so let’s open it and add the ApiKey setting, as the below:



Notes:

It is always important to choose an API Key that is strong enough (a combination of a random and unique long number of alphanumeric characters), just to make it easier to guess and random.

On another note, never share the same API Key with more than 1 client, the intent of the API Key is to authenticate the client or the project, so you need to keep it unique per client.

Now let’s go back to our example and explain the rest of the method:

There are several ways to read the appsettings.json file in ASP.NET Core Web API Project, but you can rely on the dependency injection and configuration extensions libraries of Microsoft to get load the settings file and read its values:

var appSettings = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();
var apiKey = appSettings.GetValue<string>(apiKeyName);

Now we have obtained our API Key value that is defined within the appsettings.json file, we will match it versus the extracted API Key value from the request headers collection. If both match, then we are good to route the request to the controller to run its intended HTTP action (get, post…etc)

Otherwise, we will fail the request with a 401 Unauthorized response and a message indicating that the client is unauthorized.

if (!apiKey.Equals(extractedApiKey))
            {
                context.Result = new ContentResult()
                {
                    StatusCode = 401,
                    Content = "Unauthorized client"
                };
                return;
                }

The Decoration

Now, the final part we want here is that we need to decorate our Controller with the ApiKey Attribute so that we can authenticate the client that is calling our endpoint

So open WeatherForecastController and add [ApiKey] above the WeatherForecastController class:

[ApiKeyAuth]
public class WeatherForecastController : ControllerBase

Make sure to include the new namespace at the top of the controller class:

using APIKeyAuthentication.CustomeAttributes;


Now let’s run our application and notice the message on the browser:



Testing on Postman

To have better visibility of what’s happening and control our testing parameters we will be using Postman.

Keep the localhost running on your browser, and open Postman.

Now, let’s try to run the same URL without sending anything in the headers, notice the status is: 401 Unauthorized and the response body is showing the message “API Key was not provided”

401 Unauthorized. API Key was not provided.



Now let’s try to send the correct header name but with the wrong value, you will get the same Status as 401,

401 Unauthorized. Unauthorized Client.



Now let’s make our client pass the validation by sending the correct API Key in the header:

200 OK



And now we have a response code of 200 OK and the response body is the actual data returned by the default GET method of /weatherforecast endpoint.

2. API Key Authentication Using a Custom Middleware

With a custom ASP.NET Core Middleware, you are able to intercept and process the request object in a single place.

You can intercept each and every request that comes to your published web APIs and tap into the request headers collection and search for the API key header and validate its value.

So we will be doing almost exactly the same logic which we did in our custom attribute but this time within a middleware.

Let’s begin by creating a new folder with the name ‘CustomeMiddleware’ and then followed by a class file with the name ApiKeyAuthMiddleware:



What defines a middleware is its constructor that takes an instance of RequestDelegate Class, this instance is actually the pipeline passed between the ASP.NET Core Middleware collection. so this custom middleware will also receive this instance of pipeline and do some operations on it.

The next important thing is the InvokeAsync method that you need to define in this middleware so that it will contain the main process and in our case, the main process will be to search and validate the ApiKey header name and value within the HTTP context request headers collection, so this need to be passed in the method argument.

namespace APIKeyAuthentication.CustomeMiddleware
{
    public class ApiKeyAuthMiddleware
    {
        private readonly RequestDelegate _next;
        private const string apiKeyName = "ApiKey";
        public ApiKeyAuthMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        public async Task InvokeAsync(HttpContext context)
        {
            if (!context.Request.Headers.TryGetValue(apiKeyName, out var extractedApiKey))
            {
                context.Response.StatusCode = 401;
                await context.Response.WriteAsync("Api Key not given with Middleware ");
                return;
            }
            var appSettings = context.RequestServices.GetRequiredService<IConfiguration>();
            var key = appSettings.GetValue<string>(apiKeyName);
            if (!key.Equals(extractedApiKey))
            {
                context.Response.StatusCode = 401;
                await context.Response.WriteAsync("Api Key is not valid /Unauthorized with ApiKeyAuthMiddleware");
                return;
            }
            await _next(context);
        }
    }
}


It is somehow similar to what we have done in the custom attribute, but the main difference that you will notice here is that we cannot directly set the Response object of the context but we have to assign the status code and message separately.

context.Response.StatusCode = 401;
await context.Response.WriteAsync("Api Key not given with Middleware");

Now the middleware has to be injected or included in our pipeline, we will do this in the Program.cs class

Add the following line:

app.UseMiddleware<ApiKeyAuthMiddleware>();

And below is how your program.cs file should look like this while injecting the ApiKeyAuthMiddleware into the app pipeline:



This way you will be applying this custom API Key Middleware over every single controller in your project, not just specific controller or method like the custom attributes.

Middleware is also very useful in other situations such as where you want to apply logging and general exception handling over your all APIs. There are so many use cases for using the ASP.NET Core Middleware.

So now, just before you run the application again, just make sure to remove the [ApiKey] attribute from your WeatherForecastController so that we can test the new middleware

Now let’s run the application and see.



401 Unauthorized. API Key was not provided. (Using ApiKeyAuthMiddleware)



401 Unauthorized. Unauthorized Client. Using ApiKeyAuthMiddleware



200 OK



This way you will be applying the HTTP message handler over every single endpoint not just specific like the custom attributes, where you can decorate the endpoints of your choice with the custom attribute to check for the API key.

Summary

We have seen how API Key Authentication in  ASP.NET Core Web API with 2 ways of implementing the API Key Authentication: Custom Attributes and Custom Middleware.




---------------------------------

Output caching in Asp.net Core 7.0 Preview 6

 In the previous article, we discussed ASP.NET Core and Blazor updates in .NET 7 Preview 6

In this article, we will discuss Output caching in .Net 7 previews 6.

 Output caching is the new middleware in asp.net core for .NET 7 preview 6 which helps us to store results data from our web application and then get data from a caching instead of analyzing them every time, this improves the performance and uses resources for other activities. 

To start working with output caching, need to use the AddOutputCache extension method in IServiceCollection and UseOutputCache extension method in IApplicationBuilder.

First let's create an application in Visual Studio 2022, after creating an application let's go to Program.cs class, you will see the below code in Program.cs class.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOutputCache();

var app = builder.Build();

app.UseOutputCache();

app.MapGet("/", () => "Hello World!");

app.Run();

in the program class, you can see we have builder.Services.AddOutputCache(); and app.UseOutputCache();

This helps us to do output caching.Net core 7.

Let's understand output caching with an example that prints the current date and time

app.MapGet("/Current_time", () => DateTime.Now.ToString());
So in the above code whenever we refresh the browser, it displays the current date and time, now let's add caching to the above code

After doing the above changes then we need to configure the output caching on endpoints like below

app.MapGet("/Current_time", () => DateTime.Now.ToString());
app.MapGet("/Current_time_cached", () => DateTime.Now.ToString())
.CacheOutput();


Now if you go to the browser and refresh the page, it will not change the date and time. so when you land the first time on the page, it caches the date and time, and 2nd time it doesn't refresh it and you get the cached output every time. 

If you provide a more dynamic API that receives parameters using query strings. You can vary the cache by the query string
Requests which are coming from the web are sent to the “/
Current_time_cached” check for the current time. The “/Current_time_cached” endpoint uses the.CacheOutput() extension method, by using it, each request to “/Current_time_cached” after the first one will get cached response. 

Even we can customize the output caching by using VaryByQuery. 

We can control the caching using VaryByQuery by passing parameters as below.

// Cached entries will vary by culture, but any other additional query 
// is ignored and returns the same cached content.
app.MapGet("/query
", () => DateTime.Now.ToString().CacheOutput(p=>p.VaryByQuery("culture")); // VaryByQuery allow us to add more than one query string like below app.MapGet("/query", () => DateTime.Now.ToString()).CacheOutput(p => p.VaryByQuery("time", "culture", "format"));

Now in the above example, if you want to reduce the caching output for a particular time, also we can do like below

 builder.Services.AddOutputCache(options =>
 {
     options.DefaultExpirationTimeSpan = TimeSpan.FromSeconds(20);
 });
As shown in the above code, we can reduce the output cache expiration time, now it will store the output cache for 20 seconds and after that, if we will refresh the page, it will change the date and time.

-------------------------------------------------------------




Learn multithreading and asynchronous programming and parallel programming in C# and .Net

Learn multithreading and asynchronous programming and parallel programming in C# and .Net

 In this course, we will cover the below topics

•Multithreading from basic to advance level •Asynchronous Programming in C# •how to write asynchronous programming using Task •Parallel Programming • Parallel For /Foreach in C# •Parallel Invoke in C# •Parallel Linq in C#
Prerequisite •Visual studio should install on system 2013 or higher version •Basic knowledge of C# programming •Willing to learn new things What You will get from this Course •Source code will be available as per the topic we cover. •Confident on multithreading,asynchronous, and parallel programming

Multithreading  in C#

  1. MultiThreading introduction in C# | Video
  2. What is multiTasking | Video

  3. Threading in C# | Video

  4. Thread Class in C# | Video

  5. Life Cycle of a thread in C# | Video

  6. Drawbacks of Single-Threaded Applications | Video

  7. Implement multithreading in C# | Video

  8. Constructors of Thread class in C# | Video

  9. ParameterizedThreadStart delegate in C# | Video

  10. Passing data to the Thread function in a type safe manner in C# | Video

  11. Retrieving data from Thread function using callback method | Video

  12. Thread.Join and Thread.IsAlive functions of thread class | Video

  13. Protecting shared resources from concurrent access in multithreading by locking in C# | Video

  14. Protecting shared resources from concurrent access in multithreading by monitor in C# | Video

  15. Difference between Locking and Monitor in Multithreading | Video

  16. Monitor pulse, wait and pulseAll Method in multithreading in C# | Video

  17.  ManualResetEvent in Multithreading in C# | Video

  18. AutoResetEvent in multithreading in C# | Video

  19.  Mutex in multithreading in C#  | Video

  20.  Semaphore in multithreading in C# | Video

  21. Deadlock in multithreading in C# | Video

  22. Resolve Deadlock in multithreading in C# | Video

  23. Thread Pool in C# | Video

  24.  Performance testing using and without using Thread Pool in C# | Video

  25. Performance Testing of a Multithreaded Application in C# | | Video

Asynchronous Programming in C#

  1. Asynchronous programming Introduction in C# | Video

  2. Synchronous Programming With C# | Video

  3. Solution to the Synchronous Problem With C# | Video

  4. Asynchronous Programming Patterns in .Net |  Video

  5. Asynchronous Programming Model Pattern in .Net | Video
  6. Event Based Asynchronous Programming Patterns in .Net | Video

  7. Task based Asynchronous Pattern (TAP) in .Net | Video

  8. Thread Vs Task in C# | Video

  9. Creating a task object using Factory Property in C# | Video

  10.  Creating a Task object using the Run method in C# | Video

  11. Task using Wait in C# | Video

  12. Task Return Value in C# | Video

  13.  Returning Complex Type Value From a task in C# | Video

  14. Chaining Tasks by Using Continuation Tasks in C# |

  15. Create a continuation for multiple antecedents in C# | Video

  16. Different overloaded Continuation Tasks in C# |

  17. Async Await In C# | Video

  18. Return Type of Asynchronous Method In C# | Video
  19.  Exception Handling in C# Asynchronous Programming | Video

  20.  When To Use Task And Async Await in C# | Video


Parallel Programming in C#

  1. Parallel Programming introduction in C# | Video 

  2. Parallel Programming in C# | Video

  3. Task Parallel Library in C#? | Video

  4. Parallel For in C# with Examples | Video

  5. ParallelOptions class in C# | Video

  6. Terminating a Parallel Loop | Video

  7.  Parallel ForEach Loop in C# | Video

  8. Parallel Invoke in C# with Examples | Video

  9. PLINQ in C# | Video



-------------------------------------------------------------------------------------