public async Task Invoke(HttpContext context, IClientApiKeyService clientApiKeyService) { var path = context.Request.Path.Value.ToLower(); if (context.Request.Path.HasValue) { if (path.StartsWith("/sys/appenv/") || path.EndsWith("/sys/appenv") || path.StartsWith("/api/isvalid/") || path.EndsWith("/api/isvalid") || path.StartsWith("/swagger/") || path.EndsWith("/swagger")) { // These two special paths don't need api-key validation await _next.Invoke(context); return; } } if (!context.Request.Headers.Keys.Contains(ApiHttpHeaders.ApiKey) || !context.Request.Headers.Keys.Contains(ApiHttpHeaders.ApiSecret)) { context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; await context.Response.WriteAsync($"{ApiHttpHeaders.ApiKey} and/or {ApiHttpHeaders.ApiSecret} missing"); } else { string apiKey = context.Request.Headers[ApiHttpHeaders.ApiKey]; string apiSecret = context.Request.Headers[ApiHttpHeaders.ApiSecret]; string action = context.Request.Method; var serviceName = context.Request.GetServiceName(); var apiName = context.Request.GetApiName(); var result = await clientApiKeyService.IsClientApiKeyValidAsync(apiKey, apiSecret, serviceName, apiName, action); if (result.IsValid) { _logger.LogInformation(LogEvents.ApiKeyValidationPassed, path, apiKey, serviceName, apiName); // Add IDs into context to forward to actual API for client identification context.Items.Add(ApiHttpHeaders.ApiKey, apiKey); context.Items.Add(ApiHttpHeaders.KeyId, result.KeyId); context.Items.Add(ApiHttpHeaders.ApiId, result.ApiId); context.Items.Add(ApiHttpHeaders.ServiceId, result.ServiceId); await _next.Invoke(context); } else { // Validation failed _logger.LogInformation(LogEvents.ApiKeyValidationFailed, path, apiKey, serviceName, apiName); context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; await context.Response.WriteAsync(result.ToJson()); } } }
public ClientApiKeyValidationMiddleware(RequestDelegate next, IClientApiKeyService clientApiKeyService, IOptions <ApiGatewaySettings> settings) { _next = next; _clientApiKeyService = clientApiKeyService; _settings = settings.Value; if (!string.IsNullOrWhiteSpace(_settings.AllowAnonymousApiPath) && _settings.AllowAnonymousApiPath.Length > 0) { _allowAnnon = new Regex(_settings.AllowAnonymousApiPath, RegexOptions.IgnoreCase); } }