diff --git a/src/Paseto/Handlers/PasetoPurposeHandler.cs b/src/Paseto/Handlers/PasetoPurposeHandler.cs index 3b81826..7da50a2 100644 --- a/src/Paseto/Handlers/PasetoPurposeHandler.cs +++ b/src/Paseto/Handlers/PasetoPurposeHandler.cs @@ -85,6 +85,6 @@ protected virtual void ValidateIssuer(PasetoToken token, PasetoTokenValidationPa return; if (token.Payload.HasIssuer()) - new EqualValidator(token.Payload, PasetoRegisteredClaimNames.Audience).Validate(validationParameters.ValidIssuer); + new EqualValidator(token.Payload, PasetoRegisteredClaimNames.Issuer).Validate(validationParameters.ValidIssuer); } } diff --git a/tests/Paseto.Tests/PasetoValidationTest.cs b/tests/Paseto.Tests/PasetoValidationTest.cs new file mode 100644 index 0000000..d6472d2 --- /dev/null +++ b/tests/Paseto.Tests/PasetoValidationTest.cs @@ -0,0 +1,84 @@ +using System.ComponentModel; +using System.Linq; +using FluentAssertions; +using Paseto.Builder; +using Paseto.Cryptography.Key; +using Xunit; + +namespace Paseto.Tests +{ + public sealed class PasetoValidationTest + { + [Theory(DisplayName = "Should succeed on token with valid issuer")] + [InlineData(ProtocolVersion.V3, Purpose.Local)] + [InlineData(ProtocolVersion.V3, Purpose.Public)] + [InlineData(ProtocolVersion.V4, Purpose.Local)] + [InlineData(ProtocolVersion.V4, Purpose.Public)] + public void TokenWithValidIssuerValidationSucceeds(ProtocolVersion version, Purpose purpose) + { + var validationParameters = new PasetoTokenValidationParameters() + { + ValidateIssuer = true, + ValidIssuer = "valid-issuer", + }; + + var (token, decodeKey) = GenerateToken(version, purpose, "valid-issuer"); + var decoded = new PasetoBuilder() + .Use(version, purpose) + .WithKey(decodeKey) + .Decode(token, validationParameters); + + decoded.IsValid.Should().BeTrue(); + } + + [Theory(DisplayName = "Should fail on token with invalid issuer")] + [InlineData(ProtocolVersion.V3, Purpose.Local)] + [InlineData(ProtocolVersion.V3, Purpose.Public)] + [InlineData(ProtocolVersion.V4, Purpose.Local)] + [InlineData(ProtocolVersion.V4, Purpose.Public)] + public void TokenWithInValidIssuerValidationFails(ProtocolVersion version, Purpose purpose) + { + var validationParameters = new PasetoTokenValidationParameters() + { + ValidateIssuer = true, + ValidIssuer = "valid-issuer", + }; + + var (token, decodeKey) = GenerateToken(version, purpose, "invalid-issuer"); + var decoded = new PasetoBuilder() + .Use(version, purpose) + .WithKey(decodeKey) + .Decode(token, validationParameters); + + decoded.IsValid.Should().BeFalse(); + } + + private static (string token, PasetoKey decodeKey) GenerateToken(ProtocolVersion version, Purpose purpose, string issuer) + { + var builder = new PasetoBuilder().Use(version, purpose); + switch (purpose) + { + case Purpose.Local: + { + var key = builder.GenerateSymmetricKey(); + var token = builder + .WithKey(key) + .Issuer(issuer) + .Encode(); + return (token, key); + } + case Purpose.Public: + { + var keyPair = builder.GenerateAsymmetricKeyPair(Enumerable.Repeat((byte)0x00, 32).ToArray()); + var token = builder + .WithKey(keyPair.SecretKey) + .Issuer(issuer) + .Encode(); + return (token, keyPair.PublicKey); + } + default: + throw new InvalidEnumArgumentException(); + } + } + } +} \ No newline at end of file