From 64dc4eacf6bec1c09d46ec4bfa0e60bb8ae3b78b Mon Sep 17 00:00:00 2001 From: SondreB Date: Sun, 16 Aug 2020 18:30:31 +0200 Subject: [PATCH] Add path-based filtering support for API keys --- .../Authentication/ApiKey.cs | 2 ++ .../ApiKeyAuthenticationHandler.cs | 13 ++++++++ .../Blockcore.Features.NodeHost/Startup.cs | 3 ++ .../appsettings.json | 13 -------- src/Node/Blockcore.Node/appsettings.json | 31 +++++++++++++++++++ 5 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 src/Node/Blockcore.Node/appsettings.json diff --git a/src/Features/Blockcore.Features.NodeHost/Authentication/ApiKey.cs b/src/Features/Blockcore.Features.NodeHost/Authentication/ApiKey.cs index 3e0a48527..2efdab624 100644 --- a/src/Features/Blockcore.Features.NodeHost/Authentication/ApiKey.cs +++ b/src/Features/Blockcore.Features.NodeHost/Authentication/ApiKey.cs @@ -20,5 +20,7 @@ public class ApiKey //public DateTime ValidTo { get; set; } // TODO: Add support for time-activated API keys. public IReadOnlyCollection Roles { get; set; } + + public IReadOnlyCollection Paths { get; set; } } } diff --git a/src/Features/Blockcore.Features.NodeHost/Authentication/ApiKeyAuthenticationHandler.cs b/src/Features/Blockcore.Features.NodeHost/Authentication/ApiKeyAuthenticationHandler.cs index b285b5f35..5e79ee8f8 100644 --- a/src/Features/Blockcore.Features.NodeHost/Authentication/ApiKeyAuthenticationHandler.cs +++ b/src/Features/Blockcore.Features.NodeHost/Authentication/ApiKeyAuthenticationHandler.cs @@ -51,6 +51,19 @@ protected override async Task HandleAuthenticateAsync() if (existingApiKey != null) { + // First verify the path access is enabled, if so we'll perform a validation here. + if (this.Request.Path.HasValue && existingApiKey.Paths != null && existingApiKey.Paths.Count > 0) + { + string path = this.Request.Path.Value; + bool hasAccess = existingApiKey.Paths.Any(p => path.StartsWith(p)); + + if (!hasAccess) + { + // Return NoResult and return standard 401 Unauthorized result. + return AuthenticateResult.NoResult(); + } + } + var claims = new List { new Claim(ClaimTypes.Name, existingApiKey.Owner) diff --git a/src/Features/Blockcore.Features.NodeHost/Startup.cs b/src/Features/Blockcore.Features.NodeHost/Startup.cs index ce85dad73..3f25197d7 100644 --- a/src/Features/Blockcore.Features.NodeHost/Startup.cs +++ b/src/Features/Blockcore.Features.NodeHost/Startup.cs @@ -49,6 +49,9 @@ public void ConfigureServices(IServiceCollection services) { NodeHostSettings hostSettings = fullNode.Services.ServiceProvider.GetService(); + // Make the configuration available to custom features. + services.AddSingleton(this.Configuration); + services.AddLogging(loggingBuilder => { loggingBuilder.AddConfiguration(this.Configuration.GetSection("Logging")); diff --git a/src/Features/Blockcore.Features.NodeHost/appsettings.json b/src/Features/Blockcore.Features.NodeHost/appsettings.json index c8c14792b..3293d7acd 100644 --- a/src/Features/Blockcore.Features.NodeHost/appsettings.json +++ b/src/Features/Blockcore.Features.NodeHost/appsettings.json @@ -6,18 +6,5 @@ "System": "Information", "Microsoft": "Information" } - }, - "Blockcore": { - "API": { - "Keys": [ - { - "Id": 1, - "Enabled": false, - "Owner": "Admin", - "Key": "1ca8f906-a23e-48b2-8b83-e95290986d0e", - "Roles": [ "User", "Admin" ] - } - ] - } } } diff --git a/src/Node/Blockcore.Node/appsettings.json b/src/Node/Blockcore.Node/appsettings.json new file mode 100644 index 000000000..972f2d5fb --- /dev/null +++ b/src/Node/Blockcore.Node/appsettings.json @@ -0,0 +1,31 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Information", + "System": "Information", + "Microsoft": "Information" + } + }, + "Blockcore": { + "API": { + "Keys": [ + { + "Id": 1, + "Enabled": false, + "Owner": "Admin", + "Key": "1ca8f906-a23e-48b2-8b83-e95290986d0e", + "Roles": [ "User", "Admin" ] + }, + { + "Id": 2, + "Enabled": false, + "Owner": "Registry", + "Key": "132525f1-46d2-45eb-bfe5-8a354b63ce36", + "Roles": [ "User" ], + "Paths": [ "/api/identity", "/api/storage", "/.well-known" ] + } + ] + } + } +} \ No newline at end of file