From 9101865d2bda8f8494994d99c6b3cd70e9053834 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Anders=20M=C3=B6rner?= <anmo@multinet.se>
Date: Tue, 24 Sep 2024 12:03:24 +0200
Subject: [PATCH] fix problem with timestamp in WsMessageFilter

---
 .../MessageFilter/WsMessageFilterTests.cs     | 35 +++++++++++++++++++
 src/SoapCore/WsMessageFilter.cs               |  6 +++-
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/src/SoapCore.Tests/MessageFilter/WsMessageFilterTests.cs b/src/SoapCore.Tests/MessageFilter/WsMessageFilterTests.cs
index a9bc3707..456568ad 100644
--- a/src/SoapCore.Tests/MessageFilter/WsMessageFilterTests.cs
+++ b/src/SoapCore.Tests/MessageFilter/WsMessageFilterTests.cs
@@ -33,6 +33,19 @@ public async Task IncorrectCredentialsNotAuthrorized()
 			await filter.OnRequestExecuting(CreateMessage(usernameToken));
 		}
 
+		[TestMethod]
+		[ExpectedException(typeof(InvalidCredentialException))]
+		public async Task IncorrectCredentialsWithTimestampNotAuthrorized()
+		{
+			var usernameToken = new XElement(
+				_wsse + "UsernameToken",
+				new XElement(_wsse + "Username", "INVALID_USERNAME"),
+				new XElement(_wsse + "Password", "INAVLID_PASSWORD"));
+
+			var filter = new WsMessageFilter("yourusername", "yourpassword");
+			await filter.OnRequestExecuting(CreateMessageWithTimestamp(usernameToken));
+		}
+
 		[TestMethod]
 		public async Task PasswordIsOptional()
 		{
@@ -166,5 +179,27 @@ private static Message CreateMessage(XNode usernameToken)
 			var doc = new XDocument(envelope);
 			return Message.CreateMessage(doc.CreateReader(), int.MaxValue, MessageVersion.Soap11);
 		}
+
+		private static Message CreateMessageWithTimestamp(XNode usernameToken)
+		{
+			var envelope = new XElement(
+				_soapenv11 + "Envelope",
+				new XAttribute(XNamespace.Xmlns + "wsse", _wsse.NamespaceName),
+				new XAttribute(XNamespace.Xmlns + "soap", _soapenv11.NamespaceName),
+				new XElement(
+					_soapenv11 + "Header",
+					new XElement(
+						_wsse + "Security",
+						new XElement(_wsse + "Timestamp", new XElement(_wsse + "Created"), new XElement(_wsse + "Expires")),
+						usernameToken)),
+				new XElement(
+					_soapenv11 + "Body",
+					new XElement(
+						XName.Get("Ping", "http://tempuri.org/"),
+						"abc")));
+
+			var doc = new XDocument(envelope);
+			return Message.CreateMessage(doc.CreateReader(), int.MaxValue, MessageVersion.Soap11);
+		}
 	}
 }
diff --git a/src/SoapCore/WsMessageFilter.cs b/src/SoapCore/WsMessageFilter.cs
index 78234d46..d2183752 100644
--- a/src/SoapCore/WsMessageFilter.cs
+++ b/src/SoapCore/WsMessageFilter.cs
@@ -70,7 +70,11 @@ private WsUsernameToken GetWsUsernameToken(Message message)
 				if (message.Headers[i].Name.ToLower() == "security")
 				{
 					using var reader = message.Headers.GetReaderAtHeader(i);
-					reader.Read();
+					while (!reader.EOF && reader.LocalName != "UsernameToken")
+					{
+						reader.Read();
+					}
+
 					var serializer = new XmlSerializer(typeof(WsUsernameToken));
 					wsUsernameToken = (WsUsernameToken)serializer.Deserialize(reader);
 				}