diff --git a/src/NetDevPack.Security.Jwt.Core/Interfaces/IJwtService.cs b/src/NetDevPack.Security.Jwt.Core/Interfaces/IJwtService.cs index 021601e..b5ea662 100644 --- a/src/NetDevPack.Security.Jwt.Core/Interfaces/IJwtService.cs +++ b/src/NetDevPack.Security.Jwt.Core/Interfaces/IJwtService.cs @@ -17,6 +17,7 @@ public interface IJwtService Task GetCurrentEncryptingCredentials(); Task> GetLastKeys(int? i = null); Task RevokeKey(string keyId, string reason = null); + Task GenerateNewKey(); } [Obsolete("Deprecate, use IJwtServiceInstead")] public interface IJsonWebKeySetService : IJwtService{} \ No newline at end of file diff --git a/src/NetDevPack.Security.Jwt.Core/Jwt/JwtService.cs b/src/NetDevPack.Security.Jwt.Core/Jwt/JwtService.cs index b1e562b..b3e6746 100644 --- a/src/NetDevPack.Security.Jwt.Core/Jwt/JwtService.cs +++ b/src/NetDevPack.Security.Jwt.Core/Jwt/JwtService.cs @@ -79,6 +79,15 @@ public async Task RevokeKey(string keyId, string reason = null) await _store.Revoke(key, reason); } + + public async Task GenerateNewKey() + { + var oldCurrent = await _store.GetCurrent(); + await _store.Revoke(oldCurrent); + return await GenerateKey(); + + } + private bool NeedsUpdate(KeyMaterial current) { return current == null || current.IsExpired(_options.Value.DaysUntilExpire) || current.IsRevoked; diff --git a/tests/NetDevPack.Security.Jwt.Tests/JwtTests/JwtServiceTest.cs b/tests/NetDevPack.Security.Jwt.Tests/JwtTests/JwtServiceTest.cs index 24a0e87..b093e23 100644 --- a/tests/NetDevPack.Security.Jwt.Tests/JwtTests/JwtServiceTest.cs +++ b/tests/NetDevPack.Security.Jwt.Tests/JwtTests/JwtServiceTest.cs @@ -23,6 +23,20 @@ public JwtServiceTest(WarmupInMemoryStore warmup) } + + [Fact] + public async Task Should_Create_New_Key() + { + var currentKey = await _jwksService.GetCurrentSigningCredentials(); + + var newKey = await _jwksService.GenerateNewKey(); + + newKey.KeyId.Should().NotBe(currentKey.Kid); + var newCurrentKey = await _jwksService.GetCurrentSigningCredentials(); + + newKey.KeyId.Should().Be(newCurrentKey.Kid); + } + [Fact] public async Task ShouldGenerateDefaultSigning() {