The Hackney.Core.Authorization
library enables developers to customize access to API endpoints.
It provides three main features:
This feature enables developers to restrict endpoint access to users within specific Google groups.
-
Configure
ITokenFactory
: Ensure that your API has registered theITokenFactory
service fromHackney.Core.JWT
. Typically, this is done in theStartup.cs
file by adding the following code:services.AddTokenFactory();
-
Set Environment Variable: Define an environment variable containing the list of groups with access to an endpoint. The groups should be comma-separated and have no whitespaces (unless the group name has them)
$PATCH_ENDPOINT_GOOGLE_GROUPS="group1,group2,group3,group with whitespace,group4"
You can have multiple environment variables if you want different groups to have access to different endpoints. Note: Make sure you configure this environment variable to be available locally and in your pipeline, through your
serverless.yml
andappsettings.json
files. -
Apply Authorization Filter: In your controller methods, add the
[AuthorizeEndpointByGroups("<Environment Variable Name>")]
attribute.[HttpPost] [AuthorizeEndpointByGroups("ALLOWED_GOOGLE_GROUPS_POST")] public async Task<IActionResult> CreateUser([FromBody] CreateUserRequest request) { // Your code here }
This means that the
CreateUser
endpoint will be limited to the Google groups listed in the$ALLOWED_GOOGLE_GROUPS_POST
environment variable.
To test authorization filters:
- Create a mock JWT token for a fake user with fake Google groups.
- Set the environment variable to include the same Google groups as those in the JWT token.
- Modify either the environment variable or the JWT token to include a Google group that doesn't match the other.
-
Set Environment Variable: Define an environment variable containing the list of IP addresses with access to an endpoint. The list should be semi-colon separated. For example:
$GET_ENDPOINT_WHITELISTED_IPS="127.0.0.1;243.156.218.37"
You can have multiple environment variables if you want different groups to have access to different endpoints. Note: Make sure you configure this environment variable to be available locally and in your pipeline, through your
serverless.yml
andappsettings.json
files. -
Apply Authorization Filter: In your controller methods, add the
[AuthorizeEndpointByIpWhitelist("<Environment Variable Name>")]
attribute. For example:[HttpGet] [Route("/users/{id}")] [AuthorizeEndpointByIpWhitelist("ALLOWED_IPS_GET")] public async Task<IActionResult> GetUser([FromRoute] Guid id) { // Your code here }
This means that the
GetUser
endpoint will be limited to the IP addresses listed in the$ALLOWED_IPS_GET
environment variable.
To configure a fake IP address for End-to-End (E2E) testing, follow these steps:
-
Create a MockWebApplicationFactoryWithMiddleware Class: Create a
MockWebApplicationFactoryWithMiddleware
class which extendsMockWebApplicationFactory<TStartup>
and allows you to dynamically add middleware to your startup class. Also, set up any environment variables needed.public class MockWebApplicationFactoryWithMiddleware<TStartup> : MockWebApplicationFactory<TStartup> where TStartup : class { public MockWebApplicationFactoryWithMiddleware() : base() { EnsureEnvVarConfigured("ALLOWED_IPS_GET", "127.0.0.1"); } protected override void ConfigureWebHost(IWebHostBuilder builder) { base.ConfigureWebHost(builder); builder.ConfigureAppConfiguration(b => b.AddEnvironmentVariables()) .UseStartup<MiddlewareConfigurationStartup>(); builder.ConfigureServices(services => { services.AddSingleton<Action<IApplicationBuilder>>(app => { // Add middleware to the pipeline (can have multiple) app.UseMiddleware<OverrideIpAddressMiddleware>(); }); }); } }
-
Middleware Configuration: To allow you to configure middleware in your startup code, create a
MiddlewareConfigurationStartup
class which inherits fromStartup
. (You can copy and paste this code directly without any changes)public class MiddlewareConfigurationStartup : Startup { public MiddlewareConfigurationStartup(IConfiguration configuration) : base(configuration) { } public override void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger) { var middlewareConfigurationAction = app.ApplicationServices.GetService<Action<IApplicationBuilder>>(); middlewareConfigurationAction?.Invoke(app); base.Configure(app, env, logger); } }
-
Create Override IP Address Middleware: The
OverrideIpAddressMiddleware
class is responsible for setting the remote IP address to a fake value. (You can copy and paste this code directly without any changes) Make sure to reference it in theConfigureWebHost
method.public class OverrideIpAddressMiddleware { private readonly RequestDelegate _next; public OverrideIpAddressMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { byte[] ipBytes = { 127, 0, 0, 1 }; IPAddress ipAddress = new IPAddress(ipBytes); context.Connection.RemoteIpAddress = ipAddress; await _next(context); } }
-
Create an AppTestCollection: This step involves defining a collection of tests that share a common context. In this case, the context is a
MockWebApplicationFactoryWithMiddleware<Startup>.
This factory sets up a mock web application with middleware for testing.[CollectionDefinition("AppTest middleware collection", DisableParallelization = true)] public class AppTestCollectionMiddleware : ICollectionFixture<MockWebApplicationFactoryWithMiddleware<Startup>> { // This class has no code, and is never created. Its purpose is simply // to be the place to apply [CollectionDefinition] and all the // ICollectionFixture<> interfaces. }
-
Update your references in your E2E test. In your end-to-end (E2E) tests, you need to update the collection reference to use the new
AppTestCollectionMiddleware
you just created. This ensures that the tests use the mocked IP address provided by the middleware.For example, if your test class currently looks like this:
[Collection("AppTest collection")] // ... public FetchAllContactDetailsTests(MockWebApplicationFactory<Startup> appFactory)
You should update the [Collection] attribute to reference the "AppTest middleware collection", and the
appFactory
parameter to have a type ofMockWebApplicationFactoryWithMiddleware<Startup>
:[Collection("AppTest middleware collection")] // ... public FetchAllContactDetailsTests(MockWebApplicationFactoryWithMiddleware<Startup> appFactory)
With this change, the tests in this class will now use the mocked IP address.
This feature enables developers to restrict access to an entire API based on specified Google groups.
Note: While this method is available, the preferred approach is using the lambda authorizer. Refer to the API Playbook for details.
To use the UseGoogleGroupAuthorization
middleware, add the following line to your Configure(...)
method in Startup.cs
:
app.UseGoogleGroupAuthorization();
This middleware will use REQUIRED_GOOGL_GROUPS
environment variable to get required Google groups list.
The testing process for AuthorizeEndpointByIpWhitelist
is similar to that of AuthorizeEndpointByGroups
. For detailed instructions on how to conduct these tests, please refer to the Testing section.