{"id":94789,"date":"2023-08-22T08:04:15","date_gmt":"2023-08-22T06:04:15","guid":{"rendered":"https:\/\/code-maze.com\/?p=94789"},"modified":"2024-04-04T18:06:59","modified_gmt":"2024-04-04T16:06:59","slug":"aspnetcore-api-key-authentication","status":"publish","type":"post","link":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/","title":{"rendered":"Implement API Key Authentication in ASP.NET Core"},"content":{"rendered":"<p>Many developers widely use API key authentication to secure API endpoints. This approach necessitates clients to provide a valid API key for accessing the endpoints. When implementing API key authentication in ASP.NET Core, it&#8217;s crucial to understand how to pass the API key and retrieve it from the incoming request.<\/p>\n<div style=\"padding: 20px; border-left: 5px color:#dc2323 solid; display: block; margin-bottom: 20px; box-shadow: 1px 1px 5px 0px lightgrey;\">To download the source code for the video, visit our <a href=\"https:\/\/www.patreon.com\/posts\/source-code-api-99787045?src=apiKeyAuth\" target=\"_blank\" rel=\"nofollow noopener\">Patreon page<\/a> (YouTube Patron tier).<\/div>\n<p>Let&#8217;s dive in.<\/p>\n<hr \/>\r\n<p style=\"text-align: center;\"><strong>VIDEO<\/strong>: API Key Authentication in .NET Web API.<\/p>\r\n<p style=\"text-align: center;\"><iframe width=\"560\" height=\"315\" src=https:\/\/www.youtube.com\/embed\/0mb-wkkVMbg?si=yynbazjU9O9uuR7X frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\r\n<hr \/>\n<h2><a id=\"authentication-methods\"><\/a>Authentication Methods in ASP.NET Core<\/h2>\n<p><span data-preserver-spaces=\"true\">In addition to API key authentication, we can use other authentication methods like <\/span><strong><span data-preserver-spaces=\"true\">Basic authentication, Token-based authentication, and OAuth authentication<\/span><\/strong><span data-preserver-spaces=\"true\">.<\/span><\/p>\n<p><strong>Basic authentication<\/strong> relies on a username and password combination sent in the request header. While easy to implement, it lacks advanced security features such as token expiration or refresh. This makes it less suitable for public-facing APIs, as there is a risk of exposing credentials in requests.<\/p>\n<p><strong>Token-based authentication<\/strong> issues a token, often a JSON Web Token (JWT), upon successful login. These tokens contain user-specific information and an expiration time. Unlike API key and Basic authentication, token-based authentication offers higher security. Tokens can expire, reducing the window of vulnerability if compromised, and we can cryptographically sign for added security.<\/p>\n<p><strong>OAuth<\/strong> is an authorization framework to delegate access rights to third-party applications. We commonly use it when an application needs to access resources on behalf of a user without sharing the user&#8217;s credentials. OAuth enables us to manage authorization and access control securely and in a standardized manner, making it an ideal choice for scenarios that demand granular access control.<\/p>\n<p>In summary, the choice of authentication mechanism depends on the specific use case&#8217;s security requirements and complexity.<\/p>\n<p>Before diving into the implementation details, let&#8217;s briefly discuss how to pass the API key to the server. We recommend reading <a href=\"https:\/\/code-maze.com\/aspnetcore-pass-parameters-to-http-get-action\/\" target=\"_blank\" rel=\"noopener\">how to pass parameters with a GET request in ASP.NET Core<\/a>.<\/p>\n<h2><a id=\"api-methods\"><\/a>Different Ways of\u00a0Passing API Key in a Request<\/h2>\n<p>There are several ways we can include the API key in a request:<\/p>\n<ul>\n<li>Query Parameters<\/li>\n<li>Request Body<\/li>\n<li>Request Headers<\/li>\n<\/ul>\n<p>Let&#8217;s explore each method briefly.<\/p>\n<h3><a id=\"initial-setup\"><\/a>Initial Setup<\/h3>\n<p>First, let&#8217;s add the API key in the <code>appsetting.json<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\">{\r\n  \"Logging\": {\r\n    \"LogLevel\": {\r\n      \"Default\": \"Information\",\r\n      \"Microsoft.AspNetCore\": \"Warning\"\r\n    }\r\n  },\r\n  \"AllowedHosts\": \"*\",\r\n  \"ApiKey\": \"6CBxzdYcEgNDrRhMbDpkBF7e4d4Kib46dwL9ZE5egiL0iL5Y3dzREUBSUYVUwUkN\"\r\n}<\/pre>\n<p>We add the <code>ApiKey<\/code> configuration property with the random 64-bit string value.<\/p>\n<p><strong>Please be aware that the values are currently being stored in the appsettings.json file for testing convenience. Nevertheless, when deploying your application in a production setting, it is crucial to prioritize security by opting for safer approaches like using <a href=\"https:\/\/code-maze.com\/aspnet-configuration-securing-sensitive-data\/?_gl=1*8ahrvu*_ga*MjVvTVg4M3BOa0pOenNOUk1fSjVWREh5d0pHRmhFOU5PZnYwZFdyQTdtdGU3dDJPRXBKczl5elZTUEpjRjJaVA..\" target=\"_blank\" rel=\"noopener\">environment variables<\/a> or a vault mechanism to store this information.<\/strong><\/p>\n<p>Then, let&#8217;s create a <code>Constants<\/code> class that holds two constants:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public static class Constants\r\n{\r\n    public const string ApiKeyHeaderName = \"X-API-Key\";\r\n\r\n    public const string ApiKeyName = \"ApiKey\";\r\n}<\/pre>\n<p>Next, let us create a <code>interface<\/code> in which we declare a method for validating the API key:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public interface IApiKeyValidation\r\n{\r\n    bool IsValidApiKey(string userApiKey);\r\n}<\/pre>\n<p>Finally, let&#8217;s define the <code>ApiKeyValidation<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class ApiKeyValidation : IApiKeyValidation\r\n{\r\n    private readonly IConfiguration _configuration;\r\n\r\n    public ApiKeyValidation(IConfiguration configuration)\r\n    {\r\n        _configuration = configuration;\r\n    }\r\n\r\n    public bool IsValidApiKey(string userApiKey)\r\n    {\r\n        if (string.IsNullOrWhiteSpace(userApiKey))\r\n            return false;\r\n\r\n        string? apiKey = _configuration.GetValue&lt;string&gt;(Constants.ApiKeyName);\r\n\r\n        if (apiKey == null || apiKey != userApiKey)\r\n            return false;\r\n\r\n        return true;\r\n    }\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Let\u2019s begin by implementing the<\/span> interface method <code>IsValidApiKey<\/code> <span style=\"font-weight: 400;\">and then we can inject the<\/span> <code>IConfiguration<\/code> into the constructor.<\/p>\n<p>After that, we check if the <code>userApiKey<\/code> provided is null, empty, or contains only whitespace. If the <code>userApiKey<\/code> is found to be null or empty, the method returns <code>false<\/code>, indicating an invalid API key.<\/p>\n<p>Moving on, we utilize the <code>configuration<\/code> object to retrieve the API key from the configuration using the <code>GetValue&lt;string&gt;()<\/code> method. Once we have both the API key from the configuration and the <code>userApiKey<\/code>, we compare them to determine if they match. If the keys do not match, we return <code>false<\/code>, indicating an invalid API key.<\/p>\n<p>On the other hand, if the provided <code>userApiKey<\/code> matches the API key from the configuration, we conclude that the API key is valid and return <code>true<\/code>.<\/p>\n<p>Finally, we register the <code>ApiKeyValidation<\/code> class in the <code>Program.cs<\/code> class using ASP.NET Core dependency injection container. Specifically, we use the <code>AddTransient<\/code> method to configure the service lifetime of <code>IApiKeyValidation<\/code>:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">builder.Services.AddTransient&lt;IApiKeyValidation, ApiKeyValidation&gt;();<\/code><\/p>\n<p>For further insights into dependency injection and its service lifetimes, we suggest reading our article on <a href=\"https:\/\/code-maze.com\/dependency-injection-aspnet\/\" target=\"_blank\" rel=\"noopener\">Dependency Injection in ASP.NET Core<\/a> and <a href=\"https:\/\/code-maze.com\/dependency-injection-lifetimes-aspnet-core\/\" target=\"_blank\" rel=\"noopener\">Dependency Injection Lifetimes in ASP.NET Core<\/a>.<\/p>\n<h3><a id=\"query-parameters\"><\/a>Query Parameters<\/h3>\n<p>One way to pass the API key is by appending it as a parameter in the URL&#8217;s query string. While this method is simple and straightforward, remember that the API key becomes visible in the URL, which may affect security and privacy.<\/p>\n<p>For example, we can include the API key in the request URL:<\/p>\n<p><code>https:\/\/localhost:7178\/api\/WeatherForecast?apiKey=6CBxzdYcEgNDrRhMbDpkBF7e4d4Kib46dwL9ZE5egiL0iL5Y3dzREUBSUYVUwUkN<\/code>.\u00a0<\/p>\n<p>Let&#8217;s create a GET method that takes API key parameter from the query string:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[Route(\"api\/[controller]\")]\r\n[ApiController]\r\npublic class WeatherForecastController : ControllerBase\r\n{\r\n    private readonly IApiKeyValidation _apiKeyValidation;\r\n\r\n    public WeatherForecastController(IApiKeyValidation apiKeyValidation)\r\n    {\r\n        _apiKeyValidation = apiKeyValidation;\r\n    }\r\n\r\n    [HttpGet]\r\n    public IActionResult AuthenticateViaQueryParam(string apiKey)\r\n    {\r\n        if(string.IsNullOrWhiteSpace(apiKey))\r\n            return BadRequest();\r\n\r\n        bool isValid = _apiKeyValidation.IsValidApiKey(apiKey);\r\n\r\n        if (!isValid)\r\n            return Unauthorized();\r\n\r\n        return Ok();\r\n    }\r\n}<\/pre>\n<p>We define a GET endpoint that has the <code>apiKey<\/code> parameter. Initially, we validate if the <code>apiKey<\/code> is null or white spaces, and if so, we return the <code>BadRequest()<\/code> response. Subsequently, we call the <code>IsValidApiKey<\/code> method to validate the API key we get from the query parameter.<\/p>\n<p>If the API key is not valid, we return the <code>Unauthorized<\/code> response indicating that the user is not authorized to access the requested resource. Conversely, if the API key is valid we return an <code>Ok<\/code> response indicating successful authentication.<\/p>\n<p>Let&#8217;s send a request to the endpoint with the API key as a query parameter in the request URL:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Query-Parameter-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-94792\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Query-Parameter-2.png\" alt=\"Postman Result showing the API request and response.\" width=\"982\" height=\"283\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Query-Parameter-2.png 982w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Query-Parameter-2-300x86.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Query-Parameter-2-768x221.png 768w\" sizes=\"auto, (max-width: 982px) 100vw, 982px\" \/><\/a><\/p>\n<p>As we can see, we are authenticated to access the endpoint, and it returns the status <code>200 OK<\/code>.<\/p>\n<p>Now, let&#8217;s test the same endpoint by passing the invalid API key in the query parameter:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Query-Parameter-invalid-api-key-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-94794\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Query-Parameter-invalid-api-key-2.png\" alt=\"Postman Result showing the API request and response.\" width=\"985\" height=\"458\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Query-Parameter-invalid-api-key-2.png 985w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Query-Parameter-invalid-api-key-2-300x139.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Query-Parameter-invalid-api-key-2-768x357.png 768w\" sizes=\"auto, (max-width: 985px) 100vw, 985px\" \/><\/a><\/p>\n<p>As expected, the endpoint returns the status <code>401 Unauthorized<\/code>.<\/p>\n<h3><strong><a id=\"request-body\"><\/a>Request Body<\/strong><\/h3>\n<p>Another method is to pass the API key as part of the request body. In this approach, we include the API key as a parameter in the request body. The API endpoint retrieves the API key from the request body for validation.<\/p>\n<p>Let&#8217;s create a <code>RequestModel<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class RequestModel\r\n{\r\n    public string? ApiKey { get; set; }\r\n}<\/pre>\n<p>We add the <code>ApiKey<\/code> property to hold the value for the API key.<\/p>\n<p>Subsequently, let&#8217;s define a POST method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[HttpPost]\r\npublic IActionResult AuthenticateViaBody([FromBody] RequestModel model)\r\n{\r\n    if (string.IsNullOrWhiteSpace(model.ApiKey))\r\n        return BadRequest();\r\n\r\n    string apiKey = model.ApiKey;\r\n\r\n    bool isValid = _apiKeyValidation.IsValidApiKey(apiKey);\r\n\r\n    if (!isValid)\r\n        return Unauthorized();\r\n\r\n    return Ok();\r\n}<\/pre>\n<p>We validate the <code>ApiKey<\/code> property inside the <code>RequestModel<\/code> class.<\/p>\n<p>Finally, let&#8217;s test the endpoint:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Request-Body-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-94795\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Request-Body-3.png\" alt=\"Postman Result showing the API request and response.\" width=\"982\" height=\"294\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Request-Body-3.png 982w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Request-Body-3-300x90.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Request-Body-3-768x230.png 768w\" sizes=\"auto, (max-width: 982px) 100vw, 982px\" \/><\/a><\/p>\n<p>API returns the status <span style=\"color: #222222; font-family: monospace;\"><span style=\"background-color: #e9ebec;\">200 OK<\/span><\/span>\u00a0based on validating the API key passed in the request body.<\/p>\n<h3><strong><a id=\"request-header\"><\/a>Request<\/strong> Header<\/h3>\n<p>The third method involves passing the API key as a custom header in the request. We include the API key in the header, such as <code>X-API-Key<\/code>. We can then retrieve the API key from the request headers for authentication and authorization.<\/p>\n<p>Now, let&#8217;s create a GET method to validate the API key passed via the header:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[HttpGet(\"header\")]\r\npublic IActionResult AuthenticateViaHeader()\r\n{\r\n    string? apiKey = Request.Headers[Constants.ApiKeyHeaderName];\r\n\r\n    if (string.IsNullOrWhiteSpace(apiKey))\r\n        return BadRequest();\r\n\r\n    bool isValid = _apiKeyValidation.IsValidApiKey(apiKey);\r\n\r\n    if (!isValid)\r\n        return Unauthorized();\r\n\r\n    return Ok();\r\n}<\/pre>\n<p>Inside the method, we retrieve the API key value using the <code>Request.Headers[\"X-API-Key\"]<\/code>.<\/p>\n<p>Let&#8217;s send a request to the endpoint:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Header-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-94796\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Header-1.png\" alt=\"Postman Result showing the API request and response.\" width=\"985\" height=\"281\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Header-1.png 985w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Header-1-300x86.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Header-1-768x219.png 768w\" sizes=\"auto, (max-width: 985px) 100vw, 985px\" \/><\/a><\/p>\n<p>We are passing the API key in the header with the name <code>X-API-Key<\/code>.<\/p>\n<h2><a id=\"api-authentication\"><\/a>Different Ways to Implement API Key Authentication<\/h2>\n<p>Now that we understand how to pass the API key, we will explore different approaches to implementing API key authentication in ASP.NET Core:<\/p>\n<ul>\n<li>Custom Attribute<\/li>\n<li>Custom Middleware<\/li>\n<li>Endpoint filters<\/li>\n<li>Policy-based Authorization<\/li>\n<\/ul>\n<p>Let&#8217;s take a closer look at each approach to gain a better understanding.<\/p>\n<h2><a id=\"custom-attribute\"><\/a>API Key Authentication via Custom Attributes<\/h2>\n<p>The custom attribute allows us to apply API key authentication logic at the controller or action level by adding the attribute to the desired controller or action method.<\/p>\n<p>In addition, action filters in ASP.NET Core play a crucial role in securing API endpoints. These filters intercept and modify the request or response during the execution of an action, allowing us to implement custom authorization logic. To gain more knowledge, we recommend reading our guide to implementing <a href=\"https:\/\/code-maze.com\/action-filters-aspnetcore\/\" target=\"_blank\" rel=\"noopener\">Action Filters in ASP.NET Core<\/a>.<\/p>\n<p>Firstly, let\u2019s start by creating an <code>ApiKeyAttribute<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class ApiKeyAttribute : ServiceFilterAttribute\r\n{\r\n    public ApiKeyAttribute()\r\n        : base(typeof(ApiKeyAuthFilter))\r\n    {\r\n    }\r\n}<\/pre>\n<p>We define an <code>ApiKeyAttribute<\/code> class that derives from the <code>ServiceFilterAttribute<\/code> class that allows us to apply a filter to controller actions or controller classes. <code>ServiceFilterAttribute<\/code> allows us to specify a type for the filter that will create for that attribute. We will implement our authentication logic in a class derived from <code>IAuthorizationFilter<\/code>. And using the <code>ServiceFilterAttribute<\/code> allows us to inject the class as a dependency.<\/p>\n<p>In the constructor of the <code>ApiKeyAttribute<\/code>, we call the base constructor of <code>ServiceFilterAttribute<\/code> and pass the <code>ApiKeyAuthFilter<\/code> type as an argument. This ensures that whenever the <code>ApiKeyAttribute<\/code> is applied, the associated <code>ApiKeyAuthFilter<\/code> will invoke to perform the necessary authentication logic.<\/p>\n<p>Then, let&#8217;s create an <code>ApiKeyAuthFilter<\/code>\u00a0class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class ApiKeyAuthFilter : IAuthorizationFilter\r\n{\r\n    private readonly IApiKeyValidation _apiKeyValidation;\r\n\r\n    public ApiKeyAuthFilter(IApiKeyValidation apiKeyValidation)\r\n    {\r\n        _apiKeyValidation = apiKeyValidation;\r\n    }\r\n\r\n    public void OnAuthorization(AuthorizationFilterContext context)\r\n    {\r\n        string userApiKey = context.HttpContext.Request.Headers[Constants.ApiKeyHeaderName].ToString();\r\n\r\n        if (string.IsNullOrWhiteSpace(userApiKey))\r\n        {\r\n            context.Result = new BadRequestResult();\r\n            return;\r\n        }\r\n\r\n        if(!_apiKeyValidation.IsValidApiKey(userApiKey))\r\n            context.Result = new UnauthorizedResult();\r\n    }\r\n}<\/pre>\n<p>We define an <code>ApiKeyAuthFilter<\/code> class that implements <code>IAuthorizationFilter<\/code> interface. Then we inject the <code>IApiKeyValidation<\/code> instance in the class constructor. The <code>OnAuthorization<\/code> method represents the implementation of the <code>IAuthorizationFilter<\/code> interface and gets called during the authorization process for a given request.<\/p>\n<p>Inside the <code>OnAuthorization<\/code> method, we first retrieve the API key from the request header using the constant <code>ApiKeyHeaderName<\/code>. Then we validate it using the <code>IsValidApiKey<\/code> method, and if validation fails, we set the result in the <code>AuthorizationFilterContext<\/code> to <code>UnauthorizedResult<\/code>.<\/p>\n<p>In addition, we register the <code>ApiKeyAuthFilter<\/code> as a scoped service in the DI container:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">builder.Services.AddScoped&lt;ApiKeyAuthFilter&gt;();<\/code><\/p>\n<p>We register the <code>ApiKeyAuthFilter<\/code> as a scoped service in the ASP.NET Core dependency injection container.<\/p>\n<p>Also, we should register the <code>IHttpContextAccessor<\/code> service in the <code>Program<\/code> class to be able to access the <code>HttpContext<\/code>:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\"> builder.Services.AddHttpContextAccessor();<\/code><\/p>\n<p>Finally, we apply the custom attribute to our action method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[Route(\"api\/[controller]\")]\r\n[ApiController]\r\npublic class EmployeeController : ControllerBase\r\n{\r\n    [HttpGet]\r\n    [ApiKey]\r\n    public IActionResult Get()\r\n    {\r\n        return Ok();\r\n    }\r\n}<\/pre>\n<p>We decorate our Action method <code>Get()<\/code> with the <code>[ApiKey]<\/code> attribute. The API key authentication logic in the custom attribute&#8217;s <code>OnAuthorization<\/code> method will execute before the action is invoked.<\/p>\n<p>Let&#8217;s proceed by sending a request to the endpoint:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Custom-Attribute-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-94797\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Custom-Attribute-2.png\" alt=\"Postman Result showing the API request and response.\" width=\"985\" height=\"278\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Custom-Attribute-2.png 985w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Custom-Attribute-2-300x85.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Custom-Attribute-2-768x217.png 768w\" sizes=\"auto, (max-width: 985px) 100vw, 985px\" \/><\/a><\/p>\n<p>We pass the valid API key in the request header, and we get a <code>200 OK<\/code> response.<\/p>\n<h2><a id=\"custom-middleware\"><\/a>Implementing API Key Authentication via Middleware<\/h2>\n<p>In ASP.NET Core, <a href=\"https:\/\/code-maze.com\/working-with-asp-net-core-middleware\/\" target=\"_blank\" rel=\"noopener\">middleware<\/a> is vital in handling HTTP requests and responses. It provides a pipeline through which requests flow, allowing us to intercept, process, and modify requests and response objects. By implementing custom middleware, we can incorporate API key authentication into our ASP.NET Core applications with flexibility and control.<\/p>\n<p>Custom middleware allows us to intercept incoming requests and perform authentication and authorization checks before the request reaches the endpoint.<\/p>\n<p>Let&#8217;s create a custom middleware class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class ApiKeyMiddleware\r\n{\r\n    private readonly RequestDelegate _next;\r\n    private readonly IApiKeyValidation _apiKeyValidation;\r\n\r\n    public ApiKeyMiddleware(RequestDelegate next, IApiKeyValidation apiKeyValidation)\r\n    {\r\n        _next = next;\r\n        _apiKeyValidation = apiKeyValidation;\r\n    }\r\n\r\n    public async Task InvokeAsync(HttpContext context)\r\n    {\r\n        if (string.IsNullOrWhiteSpace(context.Request.Headers[Constants.ApiKeyHeaderName]))\r\n        {\r\n            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;\r\n            return;\r\n        }\r\n\r\n        string? userApiKey = context.Request.Headers[Constants.ApiKeyHeaderName];\r\n\r\n        if (!_apiKeyValidation.IsValidApiKey(userApiKey!))\r\n        {\r\n            context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;\r\n            return;\r\n        }\r\n\r\n        await _next(context);\r\n    }\r\n}<\/pre>\n<p>Inside the <code>ApiKeyMiddleware<\/code> class, we have a parameterized constructor that accepts a <code>RequestDelegate<\/code> parameter named <code>next<\/code> and <code>IApiKeyValidation<\/code> instance. The <code>RequestDelegate<\/code> represents the next middleware component in the pipeline.<\/p>\n<p>Subsequently, we define an <code>InvokeAsync<\/code> method, which is the entry point for the middleware. We call this method for each HTTP request that passes through the middleware pipeline.<\/p>\n<p>Inside the <code>InvokeAsync<\/code> method, we retrieve the API key from the request headers using <code>context.Request.Headers[\"X-API-Key\"]<\/code>. Then we validate the API key by passing the <code>userApikey<\/code> to the <code>IsValidApiKey<\/code> method. In the event that the API key is invalid, we set the HTTP response status code to <code>401 Unauthorized<\/code> and we return from the middleware pipeline, bypassing the subsequent middleware components.<\/p>\n<p>If the API key is valid, we call the <code>await _next(context)<\/code> method to invoke the next middleware component in the pipeline.<\/p>\n<p>Now, let&#8217;s register the custom middleware just above the <code>app.UseHttpsRedirection()<\/code> middleware in the <span style=\"color: #222222; font-family: monospace;\"><span style=\"background-color: #e9ebec;\">Program<\/span><\/span>\u00a0class:<\/p>\n<p><code class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">app.UseMiddleware&lt;ApiKeyMiddleware&gt;();<\/code><\/p>\n<p>The custom middleware will execute for each incoming request, allowing us to perform the API key authentication logic.<\/p>\n<p><strong>Note: After implementing and exploring this section, comment on the middleware registration line of the code so that we can test the other implementations.<\/strong><\/p>\n<h2><a id=\"endpoint-filters\"><\/a>API Key Authentication Using Endpoint Filters<\/h2>\n<p>Endpoint filters provide a way to apply authentication and authorization logic at the endpoint level in ASP.NET Core. With endpoint filters, we can intercept requests before they reach the action methods and perform API key authentication checks.<\/p>\n<p>Let&#8217;s proceed to implement the Endpoint filters by creating a class <code>ApiKeyEndpointFilter<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class ApiKeyEndpointFilter : IEndpointFilter\r\n{\r\n    private readonly IApiKeyValidation _apiKeyValidation;\r\n\r\n    public ApiKeyEndpointFilter(IApiKeyValidation apiKeyValidation)\r\n    {\r\n        _apiKeyValidation = apiKeyValidation;\r\n    }\r\n\r\n    public async ValueTask&lt;object?&gt; InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)\r\n    {\r\n        if (string.IsNullOrWhiteSpace(context.HttpContext.Request.Headers[Constants.ApiKeyHeaderName].ToString()))\r\n            return Results.BadRequest();\r\n\r\n        string? apiKey = context.HttpContext.Request.Headers[Constants.ApiKeyHeaderName];\r\n\r\n        if (!_apiKeyValidation.IsValidApiKey(apiKey!))\r\n        {\r\n            return Results.Unauthorized();\r\n        }\r\n\r\n        return await next(context);\r\n    }\r\n}<\/pre>\n<p>The <code>ApiKeyEndpointFilter<\/code> class implements the <code>IEndpointFilter<\/code> interface, which allows us to modify the behavior of an endpoint during the request pipeline. Then we implement the <code>InvokeAsync<\/code> method. The <code>InvokeAsync<\/code> method is the main entry point for the endpoint filter. The associated endpoint calls this method during its execution.<\/p>\n<p>Then we validate the <code>apiKey<\/code>. If the <code>apiKey<\/code> is invalid, we return the <code>UnauthorizedResult<\/code> using <code>Results.Unauthorized()<\/code> method. If the <code>apiKey<\/code> is valid, we call the <code>next<\/code> delegate to proceed with the execution of the next step in the request pipeline.<\/p>\n<p>Now, we create the minimal API in the <code>Program.cs<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">app.MapGet(\"api\/product\", () =&gt;\r\n{\r\n    return Results.Ok();\r\n\r\n}).AddEndpointFilter&lt;ApiKeyEndpointFilter&gt;();<\/pre>\n<p>We add the <code>ApiKeyEndpointFilter<\/code> to the endpoint. The <code>AddEndpointFilter<\/code> extension method allows us to apply an endpoint filter to the specific endpoint. During the request pipeline for that particular endpoint, the filter executes.<\/p>\n<p>Let&#8217;s test the endpoint:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Endpoint-filter-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-94798\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Endpoint-filter-2.png\" alt=\"Postman Result showing the API request and response.\" width=\"985\" height=\"281\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Endpoint-filter-2.png 985w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Endpoint-filter-2-300x86.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Endpoint-filter-2-768x219.png 768w\" sizes=\"auto, (max-width: 985px) 100vw, 985px\" \/><\/a><\/p>\n<p>As we can see, when we pass the valid API key, we get the <code>200 OK<\/code> as response.<\/p>\n<h2><a id=\"policy-based\"><\/a>Policy-based Authorization With API Key Authentication<\/h2>\n<p>Policy-based authorization allows us to define fine-grained access control rules based on specific policies. With policy-based authorization, we can enforce API key authentication by defining a custom policy that checks for the presence and validity of the API key.<\/p>\n<p>Let&#8217;s define a custom requirement class that implements the <code>IAuthorizationRequirement<\/code> interface:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class ApiKeyRequirement : IAuthorizationRequirement\r\n{\r\n}<\/pre>\n<p>The ASP.NET Core authorization framework includes the <code>IAuthorizationRequirement<\/code> interface, which represents a requirement that an authorization policy must satisfy to succeed.<\/p>\n<p>We define an empty class <code>ApiKeyRequirement<\/code> that serves as a marker class for the specific requirement of API key authentication. By implementing the <code>IAuthorizationRequirement<\/code> interface, we indicate that this class is a requirement for authorization policies.<\/p>\n<p>Next, let&#8217;s proceed to create the custom handler class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class ApiKeyHandler : AuthorizationHandler&lt;ApiKeyRequirement&gt;\r\n{\r\n    private readonly IHttpContextAccessor _httpContextAccessor;\r\n    private readonly IApiKeyValidation _apiKeyValidation;\r\n\r\n    public ApiKeyHandler(IHttpContextAccessor httpContextAccessor, IApiKeyValidation apiKeyValidation)\r\n    {\r\n        _httpContextAccessor = httpContextAccessor;\r\n        _apiKeyValidation = apiKeyValidation;\r\n    }\r\n\r\n    protected override Task HandleRequirementAsync(\r\n        AuthorizationHandlerContext context, ApiKeyRequirement requirement)\r\n    {\r\n\r\n        string apiKey = _httpContextAccessor?.HttpContext?.Request.Headers[Constants.ApiKeyHeaderName].ToString();\r\n\r\n        if (string.IsNullOrWhiteSpace(apiKey))\r\n        {\r\n            context.Fail();\r\n            return Task.CompletedTask;\r\n        }\r\n\r\n\r\n        if (!_apiKeyValidation.IsValidApiKey(apiKey))\r\n        {\r\n            context.Fail();\r\n            return Task.CompletedTask;\r\n        }\r\n\r\n        context.Succeed(requirement);\r\n\r\n        return Task.CompletedTask;\r\n    }\r\n}<\/pre>\n<p>We derive the <code>ApiKeyHandler<\/code> class from the <code>AuthorizationHandler&lt;ApiKeyRequirement&gt;<\/code> class which is responsible for handling the API key authentication requirement. Then, we inject the <code>IHttpContextAccessor<\/code> into the <code>ApiKeyHandler<\/code> class via its constructor. The <code>IHttpContextAccessor<\/code> provides access to the current HTTP context.<\/p>\n<p>Within the <code>HandleRequirementAsync<\/code> method, we retrieve the API key from the request headers using <code>_httpContextAccessor<\/code>. Then we pass the <code>apiKey<\/code> to the <code>IsValidApiKey<\/code> method of the <code>ApiKeyValidation<\/code> class for validation. If the API key is not valid, we call the <code>context.Fail()<\/code> method to indicate that the authorization is failed.<\/p>\n<p>If the API key is valid, we set the <code>context.Succeed(requirement)<\/code> to indicate that the authorization requirement is met. Finally, we return <code>Task.CompletedTask<\/code> to signify the completion of the authorization handling.<\/p>\n<p>Finally, let&#8217;s register the <code>ApiKeyRequirement<\/code> and <code>ApiKeyHandler<\/code> in the <code>Program.cs<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">builder.Services.AddAuthentication(options =&gt;\r\n{\r\n    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;\r\n}).AddJwtBearer();\r\n\r\nbuilder.Services.AddAuthorization(options =&gt;\r\n{\r\n    options.AddPolicy(\"ApiKeyPolicy\", policy =&gt;\r\n    {\r\n        policy.AddAuthenticationSchemes(new[] { JwtBearerDefaults.AuthenticationScheme });\r\n        policy.Requirements.Add(new ApiKeyRequirement());\r\n    });\r\n});\r\n\r\nbuilder.Services.AddScoped&lt;IAuthorizationHandler, ApiKeyHandler&gt;();<\/pre>\n<p>First, let&#8217;s install the <code>Microsoft.AspNetCore.Authentication.JwtBearer<\/code> package via the NuGet package manager.<\/p>\n<p>Next, we set the default authentication scheme to <code>JwtBearerDefaults.AuthenticationScheme<\/code>, indicating that JWT Bearer authentication will be used for user authentication. Next, we add the <code>AddJwtBearer()<\/code> authentication handler to the service.<\/p>\n<p>We use the <code>AddAuthorization<\/code> method of the <code>IServiceCollection<\/code> to define and configure authorization policies. We use the <code>AddPolicy<\/code> method to add a policy named &#8216;ApiKeyPolicy.&#8217; Then we add the authentication scheme required by the &#8216;ApiKeyPolicy&#8217;. Next, we add the instance of <code>ApiKeyRequirement<\/code> to the requirements of the &#8216;ApiKeyPolicy.&#8217; By adding this requirement, the policy will require API key authentication.<\/p>\n<p>Finally, we register the <code>ApiKeyHandler<\/code> class as a scoped service and associate it with the <code>IAuthorizationHandler<\/code> interface. By doing so, we ensure that <code>ApiKeyHandler<\/code> is used to handle the API key authentication requirement when the policy is applied.<\/p>\n<p>As a final step, let&#8217;s create a GET method and apply the authorization policy:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[HttpGet(\"all\")]\r\n[Authorize(Policy = \"ApiKeyPolicy\")]\r\npublic IActionResult GetEmployees()\r\n{\r\n    return Ok();\r\n}<\/pre>\n<p>We add the <code>[Authorize(Policy = \"ApiKeyPolicy\")]<\/code> attribute to the <code>GetEmployees<\/code> action method.<\/p>\n<p>The <code>[Authorize]<\/code> attribute with <code>Policy = \"ApiKeyPolicy\"<\/code> ensures that only requests with a valid API key will be authorized to access the <code>GetEmployees<\/code> endpoint.<\/p>\n<p>First, let&#8217;s test the endpoint by passing the invalid API key:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Policy-based-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-94799\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Policy-based-2.png\" alt=\"Postman Result showing the API request and response.\" width=\"980\" height=\"274\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Policy-based-2.png 980w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Policy-based-2-300x84.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Policy-based-2-768x215.png 768w\" sizes=\"auto, (max-width: 980px) 100vw, 980px\" \/><\/a><\/p>\n<p>As we can see, API returns <code>401 Unauthorized<\/code>.<\/p>\n<p>Now, let&#8217;s pass the valid API key to the endpoint:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Policy-based-success-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-94800\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Policy-based-success-3.png\" alt=\"Postman Result showing the API request and response.\" width=\"985\" height=\"282\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Policy-based-success-3.png 985w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Policy-based-success-3-300x86.png 300w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/Policy-based-success-3-768x220.png 768w\" sizes=\"auto, (max-width: 985px) 100vw, 985px\" \/><\/a><\/p>\n<p>When we pass the valid API key, API returns the <code>200 OK<\/code> response.<\/p>\n<h2>Best Practices for API Key Authentication<\/h2>\n<p>API Key Authentication using the custom attributes offers us a straightforward and centralized way to handle API key authentication within the application codebase. We can use this approach for small to medium-sized projects with a limited number of endpoints that require API key protection.<\/p>\n<p>Using the middleware approach allows us to keep the authentication logic separate from the application code, providing better separation of concerns and reusability. Middleware-based API key authentication is suitable for larger projects with multiple endpoints and complex authentication requirements.<\/p>\n<p>Endpoint filters authentication efficiently handles the authentication for specific sets of endpoints and is suitable for applications that require different levels of API key protection based on endpoint groups.<\/p>\n<p>Policy-based Authorization is ideal for applications with intricate security requirements and roles that go beyond simple API key validation. It enables fine-grained control over who can access which resources based on their assigned roles and permissions.<\/p>\n<p>Choosing the appropriate approach based on our project&#8217;s requirements and security needs is essential. Consider factors such as flexibility, customization, and ease of implementation when deciding which approach to use.<\/p>\n<h2><a id=\"conclusion\"><\/a>Conclusion<\/h2>\n<p>API key authentication is a simple and effective method for securing API endpoints in specific scenarios. It has its strengths, and we can prefer it over other authentication approaches.<\/p>\n<p>It&#8217;s easy to implement with minimal overhead for servers and clients, making it ideal for applications needing basic security without complex interactions or third-party integrations.<\/p>\n<p><strong>When user-specific authorization is unnecessary, API key authentication provides straightforward access solely based on the API key&#8217;s validity. Additionally, it efficiently manages limited access scenarios, making it adequate for private or internal APIs with a restricted number of authenticated clients<\/strong><\/p>\n<p>In this article, we have explored various approaches for implementing API key authentication in ASP.NET Core and its best practices. We discussed how API key authentication adds a layer of security to our APIs by requiring a valid API key for authorization.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many developers widely use API key authentication to secure API endpoints. This approach necessitates clients to provide a valid API key for accessing the endpoints. When implementing API key authentication in ASP.NET Core, it&#8217;s crucial to understand how to pass the API key and retrieve it from the incoming request. Let&#8217;s dive in. Authentication Methods [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":62187,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[1806],"tags":[1916,79,586,73,47,72,45],"class_list":["post-94789","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-security","tag-api-key-authentication","tag-asp-net-core","tag-asp-net-core-web-api","tag-authentication","tag-rest-api","tag-security","tag-web-development","et-has-post-format-content","et_post_format-et-post-format-standard"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Implement API Key Authentication in ASP.NET Core - Code Maze<\/title>\n<meta name=\"description\" content=\"In this article, we learn about API key authentication in ASP.NET Core and how to implement API key authentication using various methods\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Implement API Key Authentication in ASP.NET Core - Code Maze\" \/>\n<meta property=\"og:description\" content=\"In this article, we learn about API key authentication in ASP.NET Core and how to implement API key authentication using various methods\" \/>\n<meta property=\"og:url\" content=\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/\" \/>\n<meta property=\"og:site_name\" content=\"Code Maze\" \/>\n<meta property=\"article:published_time\" content=\"2023-08-22T06:04:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-04T16:06:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"620\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Code Maze\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/CodeMazeBlog\" \/>\n<meta name=\"twitter:site\" content=\"@CodeMazeBlog\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Code Maze\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/\"},\"author\":{\"name\":\"Code Maze\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04\"},\"headline\":\"Implement API Key Authentication in ASP.NET Core\",\"datePublished\":\"2023-08-22T06:04:15+00:00\",\"dateModified\":\"2024-04-04T16:06:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/\"},\"wordCount\":2709,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"keywords\":[\"API Key authentication\",\"asp.net core\",\"asp.net core web api\",\"authentication\",\"REST API\",\"security\",\"web development\"],\"articleSection\":[\"Security\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/\",\"url\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/\",\"name\":\"Implement API Key Authentication in ASP.NET Core - Code Maze\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"datePublished\":\"2023-08-22T06:04:15+00:00\",\"dateModified\":\"2024-04-04T16:06:59+00:00\",\"description\":\"In this article, we learn about API key authentication in ASP.NET Core and how to implement API key authentication using various methods\",\"breadcrumb\":{\"@id\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#primaryimage\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png\",\"width\":1100,\"height\":620,\"caption\":\"ASP.NET Core\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/code-maze.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Implement API Key Authentication in ASP.NET Core\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/code-maze.com\/#website\",\"url\":\"https:\/\/code-maze.com\/\",\"name\":\"Code Maze\",\"description\":\"Learn. Code. Succeed.\",\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/code-maze.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/code-maze.com\/#organization\",\"name\":\"Code Maze\",\"url\":\"https:\/\/code-maze.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"width\":3511,\"height\":3510,\"caption\":\"Code Maze\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/CodeMazeBlog\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04\",\"name\":\"Code Maze\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png\",\"caption\":\"Code Maze\"},\"description\":\"This is the standard author on the site. Most articles are published by individual authors, with their profiles, but when several authors have contributed, we publish collectively as a part of this profile.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/codemaze\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog\"],\"url\":\"https:\/\/code-maze.com\/author\/codemazecontributor\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Implement API Key Authentication in ASP.NET Core - Code Maze","description":"In this article, we learn about API key authentication in ASP.NET Core and how to implement API key authentication using various methods","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/","og_locale":"en_US","og_type":"article","og_title":"Implement API Key Authentication in ASP.NET Core - Code Maze","og_description":"In this article, we learn about API key authentication in ASP.NET Core and how to implement API key authentication using various methods","og_url":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/","og_site_name":"Code Maze","article_published_time":"2023-08-22T06:04:15+00:00","article_modified_time":"2024-04-04T16:06:59+00:00","og_image":[{"width":1100,"height":620,"url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","type":"image\/png"}],"author":"Code Maze","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/CodeMazeBlog","twitter_site":"@CodeMazeBlog","twitter_misc":{"Written by":"Code Maze","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#article","isPartOf":{"@id":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/"},"author":{"name":"Code Maze","@id":"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04"},"headline":"Implement API Key Authentication in ASP.NET Core","datePublished":"2023-08-22T06:04:15+00:00","dateModified":"2024-04-04T16:06:59+00:00","mainEntityOfPage":{"@id":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/"},"wordCount":2709,"commentCount":2,"publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"image":{"@id":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","keywords":["API Key authentication","asp.net core","asp.net core web api","authentication","REST API","security","web development"],"articleSection":["Security"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/","url":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/","name":"Implement API Key Authentication in ASP.NET Core - Code Maze","isPartOf":{"@id":"https:\/\/code-maze.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#primaryimage"},"image":{"@id":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","datePublished":"2023-08-22T06:04:15+00:00","dateModified":"2024-04-04T16:06:59+00:00","description":"In this article, we learn about API key authentication in ASP.NET Core and how to implement API key authentication using various methods","breadcrumb":{"@id":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#primaryimage","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-aspnetcore.png","width":1100,"height":620,"caption":"ASP.NET Core"},{"@type":"BreadcrumbList","@id":"https:\/\/code-maze.com\/aspnetcore-api-key-authentication\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/code-maze.com\/"},{"@type":"ListItem","position":2,"name":"Implement API Key Authentication in ASP.NET Core"}]},{"@type":"WebSite","@id":"https:\/\/code-maze.com\/#website","url":"https:\/\/code-maze.com\/","name":"Code Maze","description":"Learn. Code. Succeed.","publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/code-maze.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/code-maze.com\/#organization","name":"Code Maze","url":"https:\/\/code-maze.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","width":3511,"height":3510,"caption":"Code Maze"},"image":{"@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/CodeMazeBlog"]},{"@type":"Person","@id":"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04","name":"Code Maze","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/person\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png","caption":"Code Maze"},"description":"This is the standard author on the site. Most articles are published by individual authors, with their profiles, but when several authors have contributed, we publish collectively as a part of this profile.","sameAs":["https:\/\/www.linkedin.com\/company\/codemaze\/","https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog"],"url":"https:\/\/code-maze.com\/author\/codemazecontributor\/"}]}},"_links":{"self":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/94789","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/comments?post=94789"}],"version-history":[{"count":14,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/94789\/revisions"}],"predecessor-version":[{"id":94965,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/94789\/revisions\/94965"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media\/62187"}],"wp:attachment":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media?parent=94789"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/categories?post=94789"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/tags?post=94789"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}