From 950d9c8a567273c3363f43cee454f2b95a9f5da7 Mon Sep 17 00:00:00 2001 From: Ryan Melena Date: Mon, 13 Oct 2014 21:03:25 -0500 Subject: [PATCH] Additional JWT Security Token Support Fix line endings. Add test for JavaScriptSerializer.Deserialize(string input, Type targetType). --- .../System.IdentityModel-net_4_5.csproj | 33 +++++++----- .../SecurityTokenExpiredException.cs | 54 +++++++++++++++++++ .../SecurityTokenNotYetValidException.cs | 54 +++++++++++++++++++ .../SecurityTokenReplayDetectedException.cs | 54 +++++++++++++++++++ .../System.IdentityModel.dll.sources | 6 ++- .../SignatureVerificationFailedException.cs | 54 +++++++++++++++++++ .../JavaScriptSerializer.cs | 7 ++- .../JsonDeserializer.cs | 4 +- .../JavaScriptSerializerTest.cs | 16 ++++++ .../corlib/System.Security.Claims/Claim.cs | 5 +- 10 files changed, 268 insertions(+), 19 deletions(-) create mode 100644 mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenExpiredException.cs create mode 100644 mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenNotYetValidException.cs create mode 100644 mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenReplayDetectedException.cs create mode 100644 mcs/class/System.IdentityModel/System.IdentityModel/SignatureVerificationFailedException.cs diff --git a/mcs/class/System.IdentityModel/System.IdentityModel-net_4_5.csproj b/mcs/class/System.IdentityModel/System.IdentityModel-net_4_5.csproj index 3022c52ab5b92..1e07337738e76 100644 --- a/mcs/class/System.IdentityModel/System.IdentityModel-net_4_5.csproj +++ b/mcs/class/System.IdentityModel/System.IdentityModel-net_4_5.csproj @@ -50,6 +50,7 @@ + @@ -147,9 +148,12 @@ - + + + + @@ -170,7 +174,8 @@ - + + - - - - - - + + + + + + + + + + + - - - - - @@ -236,4 +241,4 @@ - + diff --git a/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenExpiredException.cs b/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenExpiredException.cs new file mode 100644 index 0000000000000..2f10c94902927 --- /dev/null +++ b/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenExpiredException.cs @@ -0,0 +1,54 @@ +// +// SecurityTokenExpiredException.cs +// +// Author: +// Noesis Labs (Ryan.Melena@noesislabs.com) +// +// Copyright (C) 2014 Noesis Labs, LLC https://noesislabs.com +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +#if NET_4_5 + +using System; +using System.Runtime.Serialization; + +namespace System.IdentityModel.Tokens +{ + public class SecurityTokenExpiredException : SecurityTokenValidationException + { + public SecurityTokenExpiredException() + : base("ID4181: The security token has expired.") + { } + + public SecurityTokenExpiredException(string message) + : base(message) + { } + + public SecurityTokenExpiredException(string message, Exception innerException) + : base(message, innerException) + { } + + public SecurityTokenExpiredException(SerializationInfo info, StreamingContext context) + : base(info, context) + { } + } +} +#endif diff --git a/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenNotYetValidException.cs b/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenNotYetValidException.cs new file mode 100644 index 0000000000000..9f15b7b6448ca --- /dev/null +++ b/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenNotYetValidException.cs @@ -0,0 +1,54 @@ +// +// SecurityTokenNotYetValidException.cs +// +// Author: +// Noesis Labs (Ryan.Melena@noesislabs.com) +// +// Copyright (C) 2014 Noesis Labs, LLC https://noesislabs.com +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +#if NET_4_5 + +using System; +using System.Runtime.Serialization; + +namespace System.IdentityModel.Tokens +{ + public class SecurityTokenNotYetValidException : SecurityTokenValidationException + { + public SecurityTokenNotYetValidException() + : base("ID4182: The security token is not valid yet.") + { } + + public SecurityTokenNotYetValidException(string message) + : base(message) + { } + + public SecurityTokenNotYetValidException(string message, Exception innerException) + : base(message, innerException) + { } + + public SecurityTokenNotYetValidException(SerializationInfo info, StreamingContext context) + : base(info, context) + { } + } +} +#endif diff --git a/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenReplayDetectedException.cs b/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenReplayDetectedException.cs new file mode 100644 index 0000000000000..eb4a786b336f6 --- /dev/null +++ b/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/SecurityTokenReplayDetectedException.cs @@ -0,0 +1,54 @@ +// +// SecurityTokenReplayDetectedException.cs +// +// Author: +// Noesis Labs (Ryan.Melena@noesislabs.com) +// +// Copyright (C) 2014 Noesis Labs, LLC https://noesislabs.com +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +#if NET_4_5 + +using System; +using System.Runtime.Serialization; + +namespace System.IdentityModel.Tokens +{ + public class SecurityTokenReplayDetectedException : SecurityTokenValidationException + { + public SecurityTokenReplayDetectedException() + : base("ID1070: Replay has been detected for a SecurityToken.") + { } + + public SecurityTokenReplayDetectedException(string message) + : base(message) + { } + + public SecurityTokenReplayDetectedException(string message, Exception innerException) + : base(message, innerException) + { } + + public SecurityTokenReplayDetectedException(SerializationInfo info, StreamingContext context) + : base(info, context) + { } + } +} +#endif diff --git a/mcs/class/System.IdentityModel/System.IdentityModel.dll.sources b/mcs/class/System.IdentityModel/System.IdentityModel.dll.sources index 2c86355259a44..4d705d24d5794 100755 --- a/mcs/class/System.IdentityModel/System.IdentityModel.dll.sources +++ b/mcs/class/System.IdentityModel/System.IdentityModel.dll.sources @@ -3,6 +3,7 @@ Assembly/AssemblyInfo.cs System.IdentityModel/CookieTransform.cs System.IdentityModel/OpenObject.cs +System.IdentityModel/SignatureVerificationFailedException.cs System.IdentityModel.Claims/Claim.cs System.IdentityModel.Claims/ClaimSet.cs System.IdentityModel.Claims/ClaimTypes.cs @@ -100,9 +101,12 @@ System.IdentityModel.Tokens/SecurityKeyUsage.cs System.IdentityModel.Tokens/SecurityToken.cs System.IdentityModel.Tokens/SecurityTokenDescriptor.cs System.IdentityModel.Tokens/SecurityTokenException.cs +System.IdentityModel.Tokens/SecurityTokenExpiredException.cs System.IdentityModel.Tokens/SecurityTokenHandler.cs System.IdentityModel.Tokens/SecurityTokenHandlerCollection.cs System.IdentityModel.Tokens/SecurityTokenHandlerConfiguration.cs +System.IdentityModel.Tokens/SecurityTokenNotYetValidException.cs +System.IdentityModel.Tokens/SecurityTokenReplayDetectedException.cs System.IdentityModel.Tokens/SecurityTokenTypes.cs System.IdentityModel.Tokens/SecurityTokenValidationException.cs System.IdentityModel.Tokens/SessionSecurityToken.cs @@ -124,4 +128,4 @@ System.IdentityModel.Tokens/X509SubjectKeyIdentifierClause.cs System.IdentityModel.Tokens/X509ThumbprintKeyIdentifierClause.cs System.IdentityModel.Tokens/X509WindowsSecurityToken.cs System.Security.Claims/AuthenticationTypes.cs -System.ServiceModel.Security/X509CertificateValidationMode.cs \ No newline at end of file +System.ServiceModel.Security/X509CertificateValidationMode.cs diff --git a/mcs/class/System.IdentityModel/System.IdentityModel/SignatureVerificationFailedException.cs b/mcs/class/System.IdentityModel/System.IdentityModel/SignatureVerificationFailedException.cs new file mode 100644 index 0000000000000..2e1e7115ca9f1 --- /dev/null +++ b/mcs/class/System.IdentityModel/System.IdentityModel/SignatureVerificationFailedException.cs @@ -0,0 +1,54 @@ +// +// SignatureVerificationFailedException.cs +// +// Author: +// Noesis Labs (Ryan.Melena@noesislabs.com) +// +// Copyright (C) 2014 Noesis Labs, LLC https://noesislabs.com +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +#if NET_4_5 + +using System; +using System.Runtime.Serialization; + +namespace System.IdentityModel +{ + public class SignatureVerificationFailedException : Exception + { + public SignatureVerificationFailedException() + : base("ID4038: Signature verification failed.") + { } + + public SignatureVerificationFailedException(string message) + : base(message) + { } + + public SignatureVerificationFailedException(string message, Exception innerException) + : base(message, innerException) + { } + + public SignatureVerificationFailedException(SerializationInfo info, StreamingContext context) + : base(info, context) + { } + } +} +#endif diff --git a/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JavaScriptSerializer.cs b/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JavaScriptSerializer.cs index 14a03b2f0dc9c..6a147e2e03ea2 100644 --- a/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JavaScriptSerializer.cs +++ b/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JavaScriptSerializer.cs @@ -204,7 +204,12 @@ object ConvertToType (object obj, Type targetType) } public object Deserialize (string input, Type targetType) { - return DeserializeObjectInternal (input); + object obj = DeserializeObjectInternal (input); + + if (obj == null) + return Activator.CreateInstance (targetType); + + return ConvertToType (obj, targetType); } static object Evaluate (object value) { diff --git a/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JsonDeserializer.cs b/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JsonDeserializer.cs index 46bef52a7b4f6..8593e532bf0a3 100644 --- a/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JsonDeserializer.cs +++ b/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JsonDeserializer.cs @@ -833,7 +833,7 @@ bool ProcessCharacter (char ch) void CreateArray () { - var arr = new ArrayList (); + var arr = new List (); PushObject (arr); } @@ -865,7 +865,7 @@ void StoreValue (object o) { Dictionary dict = PeekObject () as Dictionary ; if (dict == null) { - ArrayList arr = PeekObject () as ArrayList; + List arr = PeekObject () as List ; if (arr == null) throw new InvalidOperationException ("Internal error: current object is not a dictionary or an array."); arr.Add (o); diff --git a/mcs/class/System.Web.Extensions/Test/System.Web.Script.Serialization/JavaScriptSerializerTest.cs b/mcs/class/System.Web.Extensions/Test/System.Web.Script.Serialization/JavaScriptSerializerTest.cs index 995590eeb2ec6..8274ef9c3f88a 100644 --- a/mcs/class/System.Web.Extensions/Test/System.Web.Script.Serialization/JavaScriptSerializerTest.cs +++ b/mcs/class/System.Web.Extensions/Test/System.Web.Script.Serialization/JavaScriptSerializerTest.cs @@ -415,6 +415,22 @@ public void TestDeserializeUnquotedKeysWithSpaces () //object oo = ser.DeserializeObject ("{value:'Purple\\r \\n monkey\\'s:\\tdishwasher'}"); } + [Test] + public void TestDeserializeNonGenericOverload() + { + JavaScriptSerializer ser = new JavaScriptSerializer(); + Assert.IsNull(ser.Deserialize("", typeof(X))); + + X s = new X(); + s.Init(); + string x = ser.Serialize(s); + + Assert.AreEqual("{\"z\":8,\"ch\":\"v\",\"ch_null\":null,\"str\":\"vwF59g\",\"b\":253,\"sb\":-48,\"sh\":-32740,\"ush\":65511,\"i\":-234235453,\"ui\":4294733061,\"l\":-9223372036854775780,\"ul\":18446744073709551612,\"f\":NaN,\"f1\":-Infinity,\"f2\":Infinity,\"f3\":-3.40282347E+38,\"f4\":3.40282347E+38,\"d\":NaN,\"d1\":-Infinity,\"d2\":Infinity,\"d3\":-1.7976931348623157E+308,\"d4\":1.7976931348623157E+308,\"de\":-1,\"de1\":0,\"de2\":1,\"de3\":-79228162514264337593543950335,\"de4\":79228162514264337593543950335,\"g\":\"000000ea-0002-0162-0102-030405060708\",\"nb\":null,\"dbn\":null,\"uri\":\"http://kostat@mainsoft/adfasdf/asdfasdf.aspx/asda/ads?a=b&c=d\",\"hash\":{\"mykey\":{\"BB\":10}},\"point\":{\"IsEmpty\":false,\"X\":150,\"Y\":150},\"MyEnum\":[1,10,345],\"MyEnum1\":[1,10,345],\"AA\":5,\"AA1\":[{\"BB\":10},{\"BB\":10}],\"BB\":18446744073709551610,\"YY\":[{\"BB\":10},{\"BB\":10}]}", x, "#A1"); + + X n = ser.Deserialize(x, typeof(X)) as X; + Assert.AreEqual(s, n, "#A2"); + } + [Test] public void TestDeserializeTypeResolver () { diff --git a/mcs/class/corlib/System.Security.Claims/Claim.cs b/mcs/class/corlib/System.Security.Claims/Claim.cs index ffb7ce7344976..0347052d23612 100644 --- a/mcs/class/corlib/System.Security.Claims/Claim.cs +++ b/mcs/class/corlib/System.Security.Claims/Claim.cs @@ -58,6 +58,9 @@ public Claim (string type, string value, string valueType, string issuer, string throw new ArgumentNullException ("type"); if (value == null) throw new ArgumentNullException ("value"); + + Properties = new Dictionary (); + Type = type; Value = value; ValueType = valueType == null ? ClaimValueTypes.String : valueType; @@ -91,4 +94,4 @@ public override string ToString () } } } -#endif \ No newline at end of file +#endif