Skip to content

Commit

Permalink
Add API key authentication for Elsa client
Browse files Browse the repository at this point in the history
Introduced an `ApiKeyHttpMessageHandler` to use an API key as the authorization header for Elsa API client. This ensures secure interaction with the Elsa server. Also made updates to the `ElsaClientOptions` class to include the API key. An `AddElsaClient` method is added with the API key parameter in `DependencyInjectionExtensions` class for convenience.
  • Loading branch information
sfmskywalker committed Dec 28, 2023
1 parent 382abfd commit bdc9d47
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Text.Json.Serialization;
using Elsa.Api.Client.Contracts;
using Elsa.Api.Client.Converters;
using Elsa.Api.Client.HttpMessageHandlers;
using Elsa.Api.Client.Options;
using Elsa.Api.Client.Resources.ActivityDescriptorOptions.Contracts;
using Elsa.Api.Client.Resources.ActivityDescriptors.Contracts;
Expand Down Expand Up @@ -31,6 +32,31 @@ namespace Elsa.Api.Client.Extensions;
[PublicAPI]
public static class DependencyInjectionExtensions
{
/// <summary>
/// Adds the Elsa client to the service collection.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="baseAddress">The base address of the Elsa API.</param>
/// <param name="apiKey">The API key to use for authentication.</param>
/// <param name="configureOptions">An optional delegate that can be used to configure the client options.</param>
/// <param name="configureBuilderOptions">An optional delegate that can be used to configure the client builder options.</param>
public static IServiceCollection AddElsaClient(this IServiceCollection services, Uri baseAddress, string apiKey, Action<ElsaClientOptions>? configureOptions = default, Action<ElsaClientBuilderOptions>? configureBuilderOptions = default)
{
services.AddScoped<ApiKeyHttpMessageHandler>();
return services.AddElsaClient(
options =>
{
options.BaseAddress = baseAddress;
options.ApiKey = apiKey;
configureOptions?.Invoke(options);
},
configureBuilderOptions: options =>
{
options.ConfigureHttpClientBuilder = builder => builder.AddHttpMessageHandler<ApiKeyHttpMessageHandler>();
configureBuilderOptions?.Invoke(options);
});
}

/// <summary>
/// Adds the Elsa client to the service collection.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Net.Http.Headers;
using Elsa.Api.Client.Options;
using Microsoft.Extensions.Options;

namespace Elsa.Api.Client.HttpMessageHandlers;

/// <summary>
/// An <see cref="HttpMessageHandler"/> that configures the outgoing HTTP request to use an API key as the authorization header.
/// </summary>
public class ApiKeyHttpMessageHandler : DelegatingHandler
{
private readonly ElsaClientOptions _options;

/// <summary>
/// Initializes a new instance of the <see cref="ApiKeyHttpMessageHandler"/> class.
/// </summary>
public ApiKeyHttpMessageHandler(IOptions<ElsaClientOptions> options)
{
_options = options.Value;
}

/// <inheritdoc />
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var apiKey = _options.ApiKey;
request.Headers.Authorization = new AuthenticationHeaderValue("ApiKey", apiKey);

return await base.SendAsync(request, cancellationToken);
}
}
6 changes: 3 additions & 3 deletions src/clients/Elsa.Api.Client/Options/ElsaClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ public class ElsaClientOptions
/// Gets or sets the base address of the Elsa server.
/// </summary>
public Uri BaseAddress { get; set; } = default!;

/// <summary>
/// Gets or sets the API key to use when authenticating with the Elsa server.
/// Gets or sets the API key function to use when authenticating with the Elsa server.
/// </summary>
public string ApiKey { get; set; } = default!;
public string? ApiKey { get; set; }

/// <summary>
/// Gets or sets a delegate that can be used to configure the HTTP client.
Expand Down

0 comments on commit bdc9d47

Please sign in to comment.