Close

Authorizing REST service using an API key

It’s quite common to use an API key as a means to authorize a REST service. The first step is to add a message handler in the Application_Start event of Global.asax: protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); GlobalConfiguration.Configuration.MessageHandlers.Add(new AuthorizationHeaderHandler()); } The AuthorizationHandler.cs file is contained in the App_Start folder. On initialization the apiKey and apiKeyEnabled setting are read from the the WebApp AppSettings. If apiKeyEnabled=true and the client doesn’t want to get the metadata (Swagger), then the apiKey is retrieved from the X-Apikey header and compared with the value in the AppSettings. That’s basically it. using Microsoft.Azure; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Security.Claims; using System.Threading; using System.Threading.Tasks; using System.Web; namespace Client.Entities._4PSTrigger.App_Start { public class AuthorizationHeaderHandler : DelegatingHandler { private static string _apiKey; private static bool _apiKeyEnabled; public AuthorizationHeaderHandler() { if (string.IsNullOrEmpty(_apiKey)) { _apiKey = CloudConfigurationManager.GetSetting(“apikey”).ToUpperInvariant(); _apiKeyEnabled = Convert.ToBoolean(CloudConfigurationManager.GetSetting(“apikeyenabled”)); } } protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { if (!request.RequestUri.AbsoluteUri.ToLowerInvariant().Contains(“swagger”) && _apiKeyEnabled) { IEnumerable<string> apiKeyHeaderValues = null; if (request.Headers.TryGetValues(“X-ApiKey”, out apiKeyHeaderValues)) { var apiKeyHeaderValue = apiKeyHeaderValues.First(); //Set ClaimSet var username = (apiKeyHeaderValue == _apiKey ? “ApiManagement” : “OtherUser”); var usernameClaim = new Claim(ClaimTypes.Name, username); var identity = new ClaimsIdentity(new[] { usernameClaim }, “ApiKey”); var principal = new ClaimsPrincipal(identity); Thread.CurrentPrincipal = principal; } else { var response = request.CreateErrorResponse(HttpStatusCode.Forbidden, ” { Error : Api-Key is missing} “); var tsc = new TaskCompletionSource<HttpResponseMessage>(); tsc.SetResult(response); // Also sets the task state to “RanToCompletion” return tsc.Task; } } return base.SendAsync(request, cancellationToken); } } }