Compare commits
2 Commits
6ac2c86520
...
0235f81003
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0235f81003 | ||
|
|
01613f2e46 |
@ -6,7 +6,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Description>DigitalData.Auth.Abstractions defines lightweight interfaces for sending and receiving authentication keys in .NET applications. It provides a unified IAuthClient for managing connections and errors, enabling seamless integration with authentication systems.</Description>
|
||||
<PackageId>DigitalData.Auth.Abstractions</PackageId>
|
||||
<Version>1.0.0</Version>
|
||||
<Version>1.1.0</Version>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>Digital Data GmbH</Product>
|
||||
<Copyright>Copyright 2025</Copyright>
|
||||
@ -14,6 +14,8 @@
|
||||
<PackageIcon>auth_icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/DigitalData.Auth</RepositoryUrl>
|
||||
<PackageTags>Digital Data Auth Authorization Authentication Abstractions</PackageTags>
|
||||
<AssemblyVersion>1.1.0</AssemblyVersion>
|
||||
<FileVersion>1.1.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageId>DigitalData.Auth.Client</PackageId>
|
||||
<Version>1.0.0</Version>
|
||||
<Version>1.1.0</Version>
|
||||
<Description>DigitalData.Auth.Client is a SignalR-based authentication client that enables applications to connect to a central authentication hub for real-time message exchange. It provides seamless connection management, automatic reconnection (RetryPolicy), and event-driven communication (ClientEvents). The package includes dependency injection support via DIExtensions, allowing easy integration into ASP.NET Core applications. With built-in retry policies and secure message handling, it ensures a reliable and scalable authentication client for real-time authentication workflows.</Description>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>Digital Data GmbH</Product>
|
||||
@ -14,8 +14,8 @@
|
||||
<PackageIcon>auth_icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/DigitalData.Auth</RepositoryUrl>
|
||||
<PackageTags>Digital Data Auth Authorization Authentication</PackageTags>
|
||||
<AssemblyVersion>1.0.0</AssemblyVersion>
|
||||
<FileVersion>1.0.0</FileVersion>
|
||||
<AssemblyVersion>1.1.0</AssemblyVersion>
|
||||
<FileVersion>1.1.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -8,6 +8,7 @@ using DigitalData.Core.Security.RSAKey;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace DigitalData.Auth.Tests.Client;
|
||||
|
||||
@ -19,7 +20,9 @@ public class AuthClientTests
|
||||
|
||||
private Func<Action<ClientParams>, ServiceProvider> Build;
|
||||
|
||||
private WebApplication? _app = null;
|
||||
private WebApplication? _app;
|
||||
|
||||
private int _port;
|
||||
|
||||
private readonly Queue<IAsyncDisposable> _disposableAsync = new();
|
||||
|
||||
@ -35,16 +38,46 @@ public class AuthClientTests
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IEnumerable<RSATokenDescriptor> _tokenDescriptors =
|
||||
[
|
||||
new()
|
||||
private static IEnumerable<RSATokenDescriptor> CreatetokenDescriptors()
|
||||
{
|
||||
return [
|
||||
new()
|
||||
{
|
||||
Issuer = "Foo",
|
||||
Audience = "Bar",
|
||||
Lifetime = new TimeSpan(1, 0, 0),
|
||||
Content = Instance.RSAFactory.CreatePrivateKeyPem()
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
private WebApplication CreateWebApplication(int port)
|
||||
{
|
||||
// Create builder and add SignalR service
|
||||
var builder = WebApplication.CreateBuilder();
|
||||
builder.Services.AddSignalR();
|
||||
builder.Services.AddCryptoFactory(new CryptoFactoryParams()
|
||||
{
|
||||
Issuer = "Foo",
|
||||
Audience = "Bar",
|
||||
Lifetime = new TimeSpan(1, 0, 0),
|
||||
Content = Instance.RSAFactory.CreatePrivateKeyPem()
|
||||
}
|
||||
];
|
||||
PemDirectory = "/",
|
||||
Decryptors = [new RSADecryptor()],
|
||||
TokenDescriptors = CreatetokenDescriptors()
|
||||
});
|
||||
builder.Services.AddMemoryCache();
|
||||
|
||||
// Listen AvailablePort and map hub
|
||||
var app = builder.Build();
|
||||
var url = $"http://localhost:{port}";
|
||||
var hubRoute = "/auth-hub";
|
||||
_hubUrl = url + hubRoute;
|
||||
app.Urls.Add(url);
|
||||
app.MapHub<AuthHub>(hubRoute);
|
||||
app.Start();
|
||||
_disposableAsync.Enqueue(app);
|
||||
return app;
|
||||
}
|
||||
|
||||
private static CryptoFactoryParams GetCryptoFactoryParamsOf(WebApplication application) => application
|
||||
.Services.GetRequiredService<IOptions<CryptoFactoryParams>>().Value;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
@ -61,27 +94,8 @@ public class AuthClientTests
|
||||
};
|
||||
|
||||
// Create and run test server
|
||||
// Create builder and add SignalR service
|
||||
var builder = WebApplication.CreateBuilder();
|
||||
builder.Services.AddSignalR();
|
||||
builder.Services.AddCryptoFactory(new CryptoFactoryParams()
|
||||
{
|
||||
PemDirectory = "/",
|
||||
Decryptors = [new RSADecryptor()],
|
||||
TokenDescriptors = _tokenDescriptors
|
||||
});
|
||||
builder.Services.AddMemoryCache();
|
||||
|
||||
// Listen AvailablePort and map hub
|
||||
var _app = builder.Build();
|
||||
var url = $"http://localhost:{AvailablePort}";
|
||||
var hubRoute = "/auth-hub";
|
||||
_hubUrl = url + hubRoute;
|
||||
_app.Urls.Add(url);
|
||||
_app.MapHub<AuthHub>(hubRoute);
|
||||
_app.Start();
|
||||
|
||||
_disposableAsync.Enqueue(_app);
|
||||
_port = AvailablePort;
|
||||
_app = CreateWebApplication(_port);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
@ -169,8 +183,10 @@ public class AuthClientTests
|
||||
opt.OnMessageReceived += (client, issuer, audience, key, logger) => publicKey = key;
|
||||
});
|
||||
var client = provider.GetRequiredService<IAuthClient>();
|
||||
await client.StartAsync();
|
||||
var expectedPublicKey = _tokenDescriptors.Get("Foo", "Bar").PublicKey.Content;
|
||||
await client.StartAsync();
|
||||
|
||||
|
||||
var expectedPublicKey = GetCryptoFactoryParamsOf(_app).TokenDescriptors.Get("Foo", "Bar").PublicKey.Content;
|
||||
|
||||
// Act
|
||||
await client.GetPublicKeyAsync("Foo", "Bar");
|
||||
@ -200,7 +216,7 @@ public class AuthClientTests
|
||||
await client.StartAsync();
|
||||
|
||||
// Act
|
||||
var expectedPublicKey = _tokenDescriptors.Get("Foo", "Bar").PublicKey;
|
||||
var expectedPublicKey = GetCryptoFactoryParamsOf(_app).TokenDescriptors.Get("Foo", "Bar").PublicKey;
|
||||
|
||||
// wait for network
|
||||
await Task.Delay(2000);
|
||||
@ -208,4 +224,38 @@ public class AuthClientTests
|
||||
// Assert
|
||||
Assert.That(publicKey.Content, Is.EqualTo(expectedPublicKey.Content));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Reconnected_ShouldUpdateAllPublicKey()
|
||||
{
|
||||
// Arrange
|
||||
var publicKey = new AsymmetricPublicKey() { Issuer = "Foo", Audience = "Bar" };
|
||||
var provider = Build(opt =>
|
||||
{
|
||||
opt.Url = _hubUrl;
|
||||
opt.PublicKeys.Add(publicKey);
|
||||
opt.RetryDelay = new TimeSpan(0, 0, 1);
|
||||
});
|
||||
var client = provider.GetRequiredService<IAuthClient>();
|
||||
await client.StartAsync();
|
||||
|
||||
// Act
|
||||
CancellationToken cancellationToken = default;
|
||||
await _app.StopAsync(cancellationToken);
|
||||
_app = null;
|
||||
|
||||
var newApp = CreateWebApplication(_port);
|
||||
|
||||
var expectedPublicKey = GetCryptoFactoryParamsOf(newApp).TokenDescriptors.Get("Foo", "Bar").PublicKey;
|
||||
|
||||
// wait for network
|
||||
await Task.Delay(5000);
|
||||
|
||||
// Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(cancellationToken.IsCancellationRequested, Is.False);
|
||||
Assert.That(publicKey.Content, Is.EqualTo(expectedPublicKey.Content));
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user