From 3ad0bb4c5081a45bb6a94265110400d895ba5e17 Mon Sep 17 00:00:00 2001 From: lafe Date: Fri, 17 Nov 2017 08:58:23 +0100 Subject: [PATCH 1/6] Updated Readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ec3ab85..68a49f3 100644 --- a/README.md +++ b/README.md @@ -2,5 +2,6 @@ This repository holds code related to authentication in SharePoint. -##SharePointPnP.IdentityModel.Extensions -Originally, Microsoft.IdentityModel.Extensions.dll is where the code for SharePoint provider-hosted apps OAuth and S2S token processing is located. Microsoft.IdentityModel.Extensions is not maintained by anyone, but SharePoint add-ins, SharePointPnP.Core and a few other things depend on it. SharePointPnP.IdentityModel.Extensions is a port of that library created by the PnP team. We reference it in OfficeDevPnP.Core (and all other supporting solutions) instead of depending on Microsoft.IdentityModel.Extensions. +## SharePointPnP.IdentityModel.Extensions + +Originally, Microsoft.IdentityModel.Extensions.dll is where the code for SharePoint provider-hosted apps OAuth and S2S token processing is located. `Microsoft.IdentityModel.Extensions` is not maintained by anyone, but SharePoint add-ins, SharePointPnP.Core and a few other things depend on it. `SharePointPnP.IdentityModel.Extensions` is a port of that library created by the PnP team. We reference it in [OfficeDevPnP.Core](https://github.com/SharePoint/PnP-Sites-Core/tree/master/Core/OfficeDevPnP.Core) (and all other supporting solutions) instead of depending on `Microsoft.IdentityModel.Extensions`. From fa838f26f3b2a9f6f886f7c78d3f42eb37d88b6f Mon Sep 17 00:00:00 2001 From: lafe Date: Fri, 17 Nov 2017 10:10:50 +0100 Subject: [PATCH 2/6] Added support for RSACng --- .../AsymmetricSignatureProviderFactory.cs | 41 ++++++++ .../S2S/Tokens/SignatureProvider.cs | 2 +- .../Tokens/X509AsymmetricSignatureProvider.cs | 2 +- .../X509RsaCngAsymmetricSignatureProvider.cs | 95 +++++++++++++++++++ ...rePointPnP.IdentityModel.Extensions.csproj | 16 +++- 5 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 SharePointPnP.IdentityModel.Extensions/S2S/Tokens/AsymmetricSignatureProviderFactory.cs create mode 100644 SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509RsaCngAsymmetricSignatureProvider.cs diff --git a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/AsymmetricSignatureProviderFactory.cs b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/AsymmetricSignatureProviderFactory.cs new file mode 100644 index 0000000..5804cc7 --- /dev/null +++ b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/AsymmetricSignatureProviderFactory.cs @@ -0,0 +1,41 @@ +using System.IdentityModel.Tokens; +using System.Security.Cryptography; + +namespace SharePointPnP.IdentityModel.Extensions.S2S.Tokens +{ + /// + /// Factory that builds the necessary based on the Cryptographic Service Provider we are getting from the + /// framework. Until .NET 4.6 the default Crypt Service Provider is . Starting with .NET 4.7, we are getting RSACng. + /// + internal class AsymmetricSignatureProviderFactory + { + /// + /// Creates a signature provider for an asymetirc encryption scheme. The + /// + /// The asymmetric security key. + /// A that uses the crypto service provider assicated with the + /// + /// Until .NET 4.6 the default Crypt Service Provider is . Starting with .NET 4.7, we are getting RSACng. + /// + public static SignatureProvider CreateSignatureProvider(X509AsymmetricSecurityKey asymmetricSecurityKey) + { + Utility.VerifyNonNullArgument("asymmetricSecurityKey", asymmetricSecurityKey); +#if NET46 + var asymmetricAlgorithm = asymmetricSecurityKey.GetAsymmetricAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", true); + if (asymmetricAlgorithm is RSACryptoServiceProvider) + { + return new X509AsymmetricSignatureProvider(asymmetricSecurityKey); + } + if (asymmetricAlgorithm is RSACng) + { + return new X509RsaCngAsymmetricSignatureProvider(asymmetricSecurityKey); + } + + throw new System.InvalidOperationException(string.Format("Could not get asymetric signature provider of type \"{0}\"", asymmetricAlgorithm.GetType().Name)); +#else + //Older versions of the .NET Framework only know the RSACryptoServiceProvider. In this case, we can use the default implementation + return new X509AsymmetricSignatureProvider(asymmetricSecurityKey); +#endif + } + } +} \ No newline at end of file diff --git a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/SignatureProvider.cs b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/SignatureProvider.cs index 3f75870..1c4f883 100644 --- a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/SignatureProvider.cs +++ b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/SignatureProvider.cs @@ -12,7 +12,7 @@ public static SignatureProvider Create(System.IdentityModel.Tokens.SigningCreden System.IdentityModel.Tokens.X509AsymmetricSecurityKey x509AsymmetricSecurityKey = signingCredentials.SigningKey as System.IdentityModel.Tokens.X509AsymmetricSecurityKey; if (x509AsymmetricSecurityKey != null) { - return new X509AsymmetricSignatureProvider(x509AsymmetricSecurityKey); + return AsymmetricSignatureProviderFactory.CreateSignatureProvider(x509AsymmetricSecurityKey); } System.IdentityModel.Tokens.SymmetricSecurityKey symmetricSecurityKey = signingCredentials.SigningKey as System.IdentityModel.Tokens.SymmetricSecurityKey; if (symmetricSecurityKey != null) diff --git a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509AsymmetricSignatureProvider.cs b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509AsymmetricSignatureProvider.cs index 66faccd..d014383 100644 --- a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509AsymmetricSignatureProvider.cs +++ b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509AsymmetricSignatureProvider.cs @@ -16,7 +16,7 @@ public X509AsymmetricSignatureProvider(System.IdentityModel.Tokens.X509Asymmetri System.Security.Cryptography.RSACryptoServiceProvider rSACryptoServiceProvider = x509Key.GetAsymmetricAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", true) as System.Security.Cryptography.RSACryptoServiceProvider; if (rSACryptoServiceProvider == null) { - throw new System.InvalidOperationException("Could not get algorithm from X509AsymmetricSecurityKey"); + throw new System.InvalidOperationException("Could not get algorithm from X509AsymmetricSecurityKey for \"RSACryptoServiceProvider\""); } this.Initialize(rSACryptoServiceProvider); } diff --git a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509RsaCngAsymmetricSignatureProvider.cs b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509RsaCngAsymmetricSignatureProvider.cs new file mode 100644 index 0000000..cfe37a9 --- /dev/null +++ b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509RsaCngAsymmetricSignatureProvider.cs @@ -0,0 +1,95 @@ +#if NET46 +using System; +using System.Security.Cryptography; + +namespace SharePointPnP.IdentityModel.Extensions.S2S.Tokens +{ + internal class X509RsaCngAsymmetricSignatureProvider : SignatureProvider + { + private bool _disposed; + + private RSACng _rsa; + + private HashAlgorithmName? _hashAlgorithm; + + public X509RsaCngAsymmetricSignatureProvider(System.IdentityModel.Tokens.X509AsymmetricSecurityKey x509Key) + { + Utility.VerifyNonNullArgument("x509Key", x509Key); + var rsaCng = x509Key.GetAsymmetricAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", true) as RSACng; + if (rsaCng == null) + { + throw new System.InvalidOperationException("Could not get algorithm from X509AsymmetricSecurityKey for \"RSACng\""); + } + this.Initialize(rsaCng); + } + + public X509RsaCngAsymmetricSignatureProvider(RSACng rsa) + { + this.Initialize(rsa); + } + + protected override void Dispose(bool disposing) + { + if (!this._disposed) + { + if (disposing) + { + if (this._hashAlgorithm != null) + { + this._hashAlgorithm = null; + } + if (this._rsa != null) + { + this._rsa.Dispose(); + this._rsa = null; + } + } + this._disposed = true; + } + } + + private void Initialize(RSACng rsa) + { + if (Utility.RequiresFipsCompliance) + { + CryptoConfig.AddOID("2.16.840.1.101.3.4.2.1", new string[] + { + "SHA256CSP" + }); + CryptoConfig.AddAlgorithm(typeof(SHA256CryptoServiceProvider), new string[] + { + "SHA256CSP" + }); + this._hashAlgorithm = new HashAlgorithmName("SHA256CSP"); + } + else + { + this._hashAlgorithm = new HashAlgorithmName("SHA256"); + } + this._rsa = rsa; + } + + public override byte[] Sign(byte[] signingInput) + { + Utility.VerifyNonNullArgument("signingInput", signingInput); + if (!this._hashAlgorithm.HasValue) + { + throw new NullReferenceException("Hash algorithm has not been set"); + } + var signaturePadding = RSASignaturePadding.Pkcs1; + return this._rsa.SignData(signingInput, this._hashAlgorithm.Value, signaturePadding); + } + + public override bool Verify(byte[] signingInput, byte[] signature) + { + Utility.VerifyNonNullArgument("signingInput", signingInput); + Utility.VerifyNonNullArgument("signature", signature); + if (!this._hashAlgorithm.HasValue) + { + throw new NullReferenceException("Hash algorithm has not been set"); + } + return this._rsa.VerifyData(signingInput, signature, this._hashAlgorithm.Value, RSASignaturePadding.Pkcs1); + } + } +} +#endif \ No newline at end of file diff --git a/SharePointPnP.IdentityModel.Extensions/SharePointPnP.IdentityModel.Extensions.csproj b/SharePointPnP.IdentityModel.Extensions/SharePointPnP.IdentityModel.Extensions.csproj index 38abc31..99d7844 100644 --- a/SharePointPnP.IdentityModel.Extensions/SharePointPnP.IdentityModel.Extensions.csproj +++ b/SharePointPnP.IdentityModel.Extensions/SharePointPnP.IdentityModel.Extensions.csproj @@ -4,7 +4,7 @@ SharePointPnP.IdentityModel.Extensions 1.2.1 SharePoint Patterns and Practices - net45 + net46 SharePointPnP.IdentityModel.Extensions SharePointPnP.IdentityModel.Extensions false @@ -13,6 +13,10 @@ 1.2.2 + + TRACE;DEBUG;NET46 + + @@ -27,4 +31,14 @@ + + + + + + + + + + From bfd63487b4c2e3803c87ce74582ced82a8042877 Mon Sep 17 00:00:00 2001 From: lafe Date: Fri, 17 Nov 2017 11:00:48 +0100 Subject: [PATCH 3/6] Added Test to project --- PnP-IdentityModel.sln | 11 ++- .../Certificate/Test.pfx | Bin 0 -> 2542 bytes .../Certificate/Test Base64.cer | 18 ++++ .../Certificate/Test.cer | Bin 0 -> 744 bytes .../Certificate/Test.pvk | Bin 0 -> 1212 bytes .../JwtTokenCreationTest.cs | 39 +++++++++ .../Properties/AssemblyInfo.cs | 20 +++++ ...ntPnP.IdentityModel.Extensions.Test.csproj | 78 ++++++++++++++++++ .../packages.config | 5 ++ 9 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 SHarePointPnP.IdentityModel.Extensions.Test/Certificate/Test.pfx create mode 100644 SharePointPnP.IdentityModel.Extensions.Test/Certificate/Test Base64.cer create mode 100644 SharePointPnP.IdentityModel.Extensions.Test/Certificate/Test.cer create mode 100644 SharePointPnP.IdentityModel.Extensions.Test/Certificate/Test.pvk create mode 100644 SharePointPnP.IdentityModel.Extensions.Test/JwtTokenCreationTest.cs create mode 100644 SharePointPnP.IdentityModel.Extensions.Test/Properties/AssemblyInfo.cs create mode 100644 SharePointPnP.IdentityModel.Extensions.Test/SharePointPnP.IdentityModel.Extensions.Test.csproj create mode 100644 SharePointPnP.IdentityModel.Extensions.Test/packages.config diff --git a/PnP-IdentityModel.sln b/PnP-IdentityModel.sln index 79f666d..e6001f3 100644 --- a/PnP-IdentityModel.sln +++ b/PnP-IdentityModel.sln @@ -1,10 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26228.4 +VisualStudioVersion = 15.0.27004.2002 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharePointPnP.IdentityModel.Extensions", "SharePointPnP.IdentityModel.Extensions\SharePointPnP.IdentityModel.Extensions.csproj", "{EB239573-1869-4DF4-8973-E01B7796DA02}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharePointPnP.IdentityModel.Extensions.Test", "SharePointPnP.IdentityModel.Extensions.Test\SharePointPnP.IdentityModel.Extensions.Test.csproj", "{575BB00A-ED1B-4B68-9F1A-C7D3FAEE0806}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,8 +17,15 @@ Global {EB239573-1869-4DF4-8973-E01B7796DA02}.Debug|Any CPU.Build.0 = Debug|Any CPU {EB239573-1869-4DF4-8973-E01B7796DA02}.Release|Any CPU.ActiveCfg = Release|Any CPU {EB239573-1869-4DF4-8973-E01B7796DA02}.Release|Any CPU.Build.0 = Release|Any CPU + {575BB00A-ED1B-4B68-9F1A-C7D3FAEE0806}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {575BB00A-ED1B-4B68-9F1A-C7D3FAEE0806}.Debug|Any CPU.Build.0 = Debug|Any CPU + {575BB00A-ED1B-4B68-9F1A-C7D3FAEE0806}.Release|Any CPU.ActiveCfg = Release|Any CPU + {575BB00A-ED1B-4B68-9F1A-C7D3FAEE0806}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9F2D97AD-51E6-4004-A7D2-E6EF0E6E86B0} + EndGlobalSection EndGlobal diff --git a/SHarePointPnP.IdentityModel.Extensions.Test/Certificate/Test.pfx b/SHarePointPnP.IdentityModel.Extensions.Test/Certificate/Test.pfx new file mode 100644 index 0000000000000000000000000000000000000000..d8872d16dc65f3fd77570f8829898efef7625d94 GIT binary patch literal 2542 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 literal 0 HcmV?d00001 diff --git a/SharePointPnP.IdentityModel.Extensions.Test/Certificate/Test Base64.cer b/SharePointPnP.IdentityModel.Extensions.Test/Certificate/Test Base64.cer new file mode 100644 index 0000000..5e8e934 --- /dev/null +++ b/SharePointPnP.IdentityModel.Extensions.Test/Certificate/Test Base64.cer @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5DCCAdCgAwIBAgIQyGg2fpyqeZVFAMQL+pssrDAJBgUrDgMCHQUAMA8xDTAL +BgNVBAMTBFRlc3QwHhcNMTYxMjMxMjMwMDAwWhcNMTcxMjMxMjMwMDAwWjAPMQ0w +CwYDVQQDEwRUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAycVE +3zBx1GX2TSGSFch9vwsfk3mPjkJztCGoyO/6taZxq2SiHo6SxzZhP46PQ4NeBV8A +kzIDlmAzbGETXYA5Ntign23m/wtCGVb521d+b+fAoiykrvLPp4+CvExjB8cDUIKS +na0w3WsdhPX2RzAQ8UU7bxPq1skExrdxj6+pAXBU0qp+l3aRwJlMJ3j7apWMV/a3 +Tr4V8203QgtRoAnl4SEY8S+mtEGGfmCfX8WCLbLJdN/UssOIe/ZOGd1iKlL7h+BG +h/6V5N+rDwxMzCUdignCt8VAUv3jz47EAfgI9DrHnmDO7a0iJC4rHrNmU6Cs8UXM +WO2JMUcqn9PjOjWPpQIDAQABo0QwQjBABgNVHQEEOTA3gBB025fpt4u1ul5U+kmP +t0unoREwDzENMAsGA1UEAxMEVGVzdIIQyGg2fpyqeZVFAMQL+pssrDAJBgUrDgMC +HQUAA4IBAQBjaZQ7r83mLOsAOrCa1etjJXQ+VP6LIlExxEfQDpQdYMB/mElRfgjx +NSTmCMpmrVvSKoePZoqV0d0LHUvZP4s8UzEUGVUuO8XHXuRSh/1A0PlAVg0v5jMw +dxg4MBGYnYBHCGdYvYJFvfo3sgS7pgzhbj7yX1PPmpHBY2aXn3B24ZIi0tOUY4vX +Ve+J8uDe22D3DvpJI3l7BSQoTzwC5M/Rd1I4k9Vw649FFv6cXJWFbX70bDMkVq1Z +xkmXR1myjYzHnhDR4uOMmjCkyiSUycrMKTbQpKV1mSjPkGDllVYUbOFdH/dFDU68 +mtH5KIdA0/npPZnzG0XTzH1YMIbG4JDD +-----END CERTIFICATE----- diff --git a/SharePointPnP.IdentityModel.Extensions.Test/Certificate/Test.cer b/SharePointPnP.IdentityModel.Extensions.Test/Certificate/Test.cer new file mode 100644 index 0000000000000000000000000000000000000000..2f80b31951ac9406d7141e4fa9b99a90b4d3a9c5 GIT binary patch literal 744 zcmXqLVtQiG#CTx=GZP~dlfa1#v${E}DyOoTW5^{CmX9aA2X9ID}w>QA+G^9 z8*?ZNvoK3YYH^8yoH(zcnW2#}5E%eL6p(9<#KqLm#HeJz%f_kI=F#?@mywZ?m4Ug5 zk)Hu*KNnLIBO}Afqb~Oi3a_Mo^HrQAdZKnexBTSF{ywMTEs85ny#KXzS>fuGMRI+U zj+-Ug_w_qB$FasUOg3VkmSCKdC>+~hX?A15{M={%xt%1#e%=nR%YS}gk}b2kw9=xUuW{Oa0CmSfus``52zEC{)@s&0DO!~-*Z z)GK~xP3;N)w%u=^=;vH>C+@%noKGJrN_^B`w#BinE@6KB(I(wZCrj>M*>t$0`kSBR z-6XA`-|Y|F+W$>`a(^{HkIxxZ*)GmQ+mAW~{e67C?+D`$jxScn=OvtbyH-g>Pg`zt zTJVB3A6?HxyzMk}*P4I%v6X56QYL0b2FArM22KVJz;KpjWU(|bZxATCJ^khO?ybAx zLVkJnZ}(olP!JZ493M?po^hN?TN`~ztGz$1YwE?j+_K&`?YnJ)4MikF^{kH`k9!i-{@3Bc zPlqsG{b$Ao}_)0`^$V2%kE`75A*Ck#Rs3CHSu6_+VuGaWe+DQ zUAjCax%+zP`_4}f?%huK&iBhxxw4v7MZ@2Q>B;$vmd?~TKOy1i)G(2phq3bC iU3vZX%)0nfqut^1&zH6{KTEq_K2sZE(01&>gu?(<1vuLP literal 0 HcmV?d00001 diff --git a/SharePointPnP.IdentityModel.Extensions.Test/Certificate/Test.pvk b/SharePointPnP.IdentityModel.Extensions.Test/Certificate/Test.pvk new file mode 100644 index 0000000000000000000000000000000000000000..0acad2ca58dbc5f5db6d4b7eebc51ec63dba788f GIT binary patch literal 1212 zcmV;t1Vj5C@wKo300002000010000G0001#1ONb_pSk1!$cOWv#Giu0^)qk>0ssI2 zBme+_bas)z{nS=J%KO*Pe^C-5U7)SnF{4JeG`*QwF91IwS+$P<3`HaY_fl<@ehyDT zG{et9*_W&gLHUO;eCN`J$UG@H?{C)N+2@+69VBT_xd={OXFX4L1cL_raQ4w5g*n6~ zA(iX*1(!;X59|+7028)t@T3hDWZW-HN)s>>SzvECXoi4Hv7)?=O=?YimS+At_ZH($}w`OCX5;$ZAa$}ulU%zp@jO%F!sS{tzwzjZeSO&&gPD(U_)M*QA@D7)i zu1nv(RqrBgj>n3X4C}lw@H0?L%J5|q>k3E$UT&1%DqRP{HXm={Qp{ps)P6j@72)D* z<{s2b#~3l?HBqc7!OS>u&v?5x3DriVw~#%>3n_2rv35a1CtP#}zV*ctft#K6>R!F! zRU-2RNxV)otuO*7L6fd+G0*)~0u0%_?O0LjW|Fz9Kn&Axb|YItg_+CF)p6MjCJUNG zWvMj3b1qTRHEawol}IXRUp3Pzfy!NBXX_{KBtzbqV?govqRep;Ao}Zri{6E?CsDc8 z2>DR}f6xjCrKe(2Q!TnaXLduc6m9BeZSFPA)C0`61DYGH9osGdLxXcdZFoCoa8MLU z;#Yv1ve~{KNM~PyFo36jeQ*_Gh7H%mh1q{^iTg5<9R1pS9&vm`+WUCc3D)RvVQhXR z{x<;K)HdUytM_vIei?e@Hg_==h)`mLh6Hjplv!Mnk+tQE_n~?}85sN6Z z_j(5MF=lMkHW~aINa$NQw^zlBXhAtHM1v^C*UM-zA!Ta0Z?wZ{d{;Tg09Hw)f&UO=vH&5k0&4Y%C^NbD4zVuazzBFR|OoyII!1b-kV*l2TAz@vfr3fmCPClp@ zikYC5aNYiNQF+ulEaY)pX7Z_ti!w1>tcFNXGeUTz6Zi~w%VJ#rbtz&ljl*2D>Dh0> z#4+-x0vyp2Ax1yM?M4q^)rr|5p&W9E8#zyvm^g-;0&=6bez43m?`5*350xpBxwM>G zuY~>ZCs%6x&hzHl7(I!mq&KrPry}M8fQBvcb7b_8|NdueP}@VS&3UYbHFMJ2UN*?o a2Sr>Kimbv=5H7a%TSJcM2)wcDkNqCR#z`yy literal 0 HcmV?d00001 diff --git a/SharePointPnP.IdentityModel.Extensions.Test/JwtTokenCreationTest.cs b/SharePointPnP.IdentityModel.Extensions.Test/JwtTokenCreationTest.cs new file mode 100644 index 0000000..17d3e71 --- /dev/null +++ b/SharePointPnP.IdentityModel.Extensions.Test/JwtTokenCreationTest.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens; +using System.Security.Cryptography.X509Certificates; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using SharePointPnP.IdentityModel.Extensions.S2S.Tokens; +using X509SigningCredentials = Microsoft.IdentityModel.SecurityTokenService.X509SigningCredentials; + +namespace SharePointPnP.IdentityModel.Extensions.Test +{ + [TestClass] + public class JwtTokenCreationTest + { + [TestMethod] + public void CreateTokenTest() + { + var certFile = @".\Certificate\Test.pfx"; + var password = "Password1+"; + + var certificate = new X509Certificate2(certFile, password); + var signingCredentials = new X509SigningCredentials(certificate, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest); + + var actorClaims = new List(); + actorClaims.Add(new JsonWebTokenClaim(JsonWebTokenConstants.ReservedClaims.NameIdentifier, "TestName")); + var actorToken = new JsonWebSecurityToken( + issuer: "Test Issuer", + audience: "TestAudience", + validFrom: new DateTime(2017, 1, 1), + validTo: new DateTime(2017, 12, 31, 23, 59, 59), + signingCredentials: signingCredentials, + claims: actorClaims); + + var actorTokenString = new JsonWebSecurityTokenHandler().WriteTokenAsString(actorToken); + + Assert.IsNotNull(actorTokenString); + Assert.AreEqual("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjhMcjBkRjJGRC00QXlUbXhzNnh4enRqYUl6WSJ9.eyJhdWQiOiJUZXN0QXVkaWVuY2UiLCJpc3MiOiJUZXN0IElzc3VlciIsIm5iZiI6IjE0ODMyMjUyMDAiLCJleHAiOiIxNTE0NzYxMTk5IiwibmFtZWlkIjoiVGVzdE5hbWUifQ.Z_8DKOQiXldAMyJj2BGNzfJd2cTm_XqEcgsAOFyeKwHGJ9yx4uYUM9V7FAUFRPzW7fsb1I2LIS8RDo_riw9m5c8xeequ1noAYbydOZIDHuM9tefplCsve0_cIzek6lV0B0jykDj7OFtJMsDs9TQEtKcjVDGkBK4BnHUwUTLB_lYdzTjMm7WXOpFxz5c74tP5vaER1nuFhtftO5Hsy7jKyRRgdhKJ2o3Do_-LGdEfG9m51dUSb5E8odVGu1vGBQVsc88a11y5uFzORL7cm6hu2RwEELIzfd7bdHruQ9BB5mpS4AGzD4QxtHs2jgYXQ4-HqWFvnpJ-Z89_xWcmo-wOKA", actorTokenString); + } + } +} diff --git a/SharePointPnP.IdentityModel.Extensions.Test/Properties/AssemblyInfo.cs b/SharePointPnP.IdentityModel.Extensions.Test/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..60acf50 --- /dev/null +++ b/SharePointPnP.IdentityModel.Extensions.Test/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("SharePointPnP.IdentityModel.Extensions.Test")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SharePointPnP.IdentityModel.Extensions.Test")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("575bb00a-ed1b-4b68-9f1a-c7d3faee0806")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SharePointPnP.IdentityModel.Extensions.Test/SharePointPnP.IdentityModel.Extensions.Test.csproj b/SharePointPnP.IdentityModel.Extensions.Test/SharePointPnP.IdentityModel.Extensions.Test.csproj new file mode 100644 index 0000000..7aee5f6 --- /dev/null +++ b/SharePointPnP.IdentityModel.Extensions.Test/SharePointPnP.IdentityModel.Extensions.Test.csproj @@ -0,0 +1,78 @@ + + + + + Debug + AnyCPU + {575BB00A-ED1B-4B68-9F1A-C7D3FAEE0806} + Library + Properties + SharePointPnP.IdentityModel.Extensions.Test + SharePointPnP.IdentityModel.Extensions.Test + v4.7 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.1.1.18\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + Always + + + + + + {EB239573-1869-4DF4-8973-E01B7796DA02} + SharePointPnP.IdentityModel.Extensions + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/SharePointPnP.IdentityModel.Extensions.Test/packages.config b/SharePointPnP.IdentityModel.Extensions.Test/packages.config new file mode 100644 index 0000000..a4b6ae9 --- /dev/null +++ b/SharePointPnP.IdentityModel.Extensions.Test/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From 50945a15e88230c3d3639ea452b0cdd722f7c96d Mon Sep 17 00:00:00 2001 From: lafe Date: Fri, 17 Nov 2017 11:06:50 +0100 Subject: [PATCH 4/6] Fixed missing file rename operation in csproj --- .../SharePointPnP.IdentityModel.Extensions.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SharePointPnP.IdentityModel.Extensions.Test/SharePointPnP.IdentityModel.Extensions.Test.csproj b/SharePointPnP.IdentityModel.Extensions.Test/SharePointPnP.IdentityModel.Extensions.Test.csproj index 7aee5f6..bcb35fe 100644 --- a/SharePointPnP.IdentityModel.Extensions.Test/SharePointPnP.IdentityModel.Extensions.Test.csproj +++ b/SharePointPnP.IdentityModel.Extensions.Test/SharePointPnP.IdentityModel.Extensions.Test.csproj @@ -50,7 +50,7 @@ - + From 20b459237593045ef0734c9c69455506944c477c Mon Sep 17 00:00:00 2001 From: Lars Fernhomberg Date: Wed, 6 Mar 2019 16:01:06 +0100 Subject: [PATCH 5/6] Fixed typos --- .../S2S/Tokens/AsymmetricSignatureProviderFactory.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/AsymmetricSignatureProviderFactory.cs b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/AsymmetricSignatureProviderFactory.cs index 5804cc7..f007bb9 100644 --- a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/AsymmetricSignatureProviderFactory.cs +++ b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/AsymmetricSignatureProviderFactory.cs @@ -10,10 +10,10 @@ namespace SharePointPnP.IdentityModel.Extensions.S2S.Tokens internal class AsymmetricSignatureProviderFactory { /// - /// Creates a signature provider for an asymetirc encryption scheme. The + /// Creates a signature provider for an asymmetric encryption scheme. The /// /// The asymmetric security key. - /// A that uses the crypto service provider assicated with the + /// A that uses the crypto service provider associated with the /// /// Until .NET 4.6 the default Crypt Service Provider is . Starting with .NET 4.7, we are getting RSACng. /// @@ -31,7 +31,7 @@ public static SignatureProvider CreateSignatureProvider(X509AsymmetricSecurityKe return new X509RsaCngAsymmetricSignatureProvider(asymmetricSecurityKey); } - throw new System.InvalidOperationException(string.Format("Could not get asymetric signature provider of type \"{0}\"", asymmetricAlgorithm.GetType().Name)); + throw new System.InvalidOperationException(string.Format("Could not get asymmetric signature provider of type \"{0}\"", asymmetricAlgorithm.GetType().Name)); #else //Older versions of the .NET Framework only know the RSACryptoServiceProvider. In this case, we can use the default implementation return new X509AsymmetricSignatureProvider(asymmetricSecurityKey); From eae71fc48036e0acb016ee4cc2036bbd837aeffe Mon Sep 17 00:00:00 2001 From: Lars Fernhomberg Date: Thu, 7 Mar 2019 10:55:51 +0100 Subject: [PATCH 6/6] Fixed issue with disposed internal key - RSACngProxy can be extended in the future to hold a copy of the key, if necessary --- .../JwtTokenCreationTest.cs | 40 +++++++++++-- .../S2S/Tokens/RSACngProxy.cs | 57 +++++++++++++++++++ .../X509RsaCngAsymmetricSignatureProvider.cs | 15 +++-- 3 files changed, 100 insertions(+), 12 deletions(-) create mode 100644 SharePointPnP.IdentityModel.Extensions/S2S/Tokens/RSACngProxy.cs diff --git a/SharePointPnP.IdentityModel.Extensions.Test/JwtTokenCreationTest.cs b/SharePointPnP.IdentityModel.Extensions.Test/JwtTokenCreationTest.cs index 17d3e71..86a1708 100644 --- a/SharePointPnP.IdentityModel.Extensions.Test/JwtTokenCreationTest.cs +++ b/SharePointPnP.IdentityModel.Extensions.Test/JwtTokenCreationTest.cs @@ -1,9 +1,9 @@ -using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using SharePointPnP.IdentityModel.Extensions.S2S.Tokens; +using System; using System.Collections.Generic; using System.IdentityModel.Tokens; using System.Security.Cryptography.X509Certificates; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using SharePointPnP.IdentityModel.Extensions.S2S.Tokens; using X509SigningCredentials = Microsoft.IdentityModel.SecurityTokenService.X509SigningCredentials; namespace SharePointPnP.IdentityModel.Extensions.Test @@ -31,9 +31,41 @@ public void CreateTokenTest() claims: actorClaims); var actorTokenString = new JsonWebSecurityTokenHandler().WriteTokenAsString(actorToken); - + Assert.IsNotNull(actorTokenString); Assert.AreEqual("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjhMcjBkRjJGRC00QXlUbXhzNnh4enRqYUl6WSJ9.eyJhdWQiOiJUZXN0QXVkaWVuY2UiLCJpc3MiOiJUZXN0IElzc3VlciIsIm5iZiI6IjE0ODMyMjUyMDAiLCJleHAiOiIxNTE0NzYxMTk5IiwibmFtZWlkIjoiVGVzdE5hbWUifQ.Z_8DKOQiXldAMyJj2BGNzfJd2cTm_XqEcgsAOFyeKwHGJ9yx4uYUM9V7FAUFRPzW7fsb1I2LIS8RDo_riw9m5c8xeequ1noAYbydOZIDHuM9tefplCsve0_cIzek6lV0B0jykDj7OFtJMsDs9TQEtKcjVDGkBK4BnHUwUTLB_lYdzTjMm7WXOpFxz5c74tP5vaER1nuFhtftO5Hsy7jKyRRgdhKJ2o3Do_-LGdEfG9m51dUSb5E8odVGu1vGBQVsc88a11y5uFzORL7cm6hu2RwEELIzfd7bdHruQ9BB5mpS4AGzD4QxtHs2jgYXQ4-HqWFvnpJ-Z89_xWcmo-wOKA", actorTokenString); } + + [TestMethod] + public void CreateTwoTokensTest() + { + var certFile = @".\Certificate\Test.pfx"; + var password = "Password1+"; + + var certificate = new X509Certificate2(certFile, password); + var signingCredentials = new X509SigningCredentials(certificate, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest); + + var actorClaims = new List(); + actorClaims.Add(new JsonWebTokenClaim(JsonWebTokenConstants.ReservedClaims.NameIdentifier, "TestName")); + var actorToken = new JsonWebSecurityToken( + issuer: "Test Issuer", + audience: "TestAudience", + validFrom: new DateTime(2017, 1, 1), + validTo: new DateTime(2017, 12, 31, 23, 59, 59), + signingCredentials: signingCredentials, + claims: actorClaims); + + var tokenHandler = new JsonWebSecurityTokenHandler(); + var firstActorTokenString = tokenHandler.WriteTokenAsString(actorToken); + + Assert.IsNotNull(firstActorTokenString); + Assert.AreEqual("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjhMcjBkRjJGRC00QXlUbXhzNnh4enRqYUl6WSJ9.eyJhdWQiOiJUZXN0QXVkaWVuY2UiLCJpc3MiOiJUZXN0IElzc3VlciIsIm5iZiI6IjE0ODMyMjUyMDAiLCJleHAiOiIxNTE0NzYxMTk5IiwibmFtZWlkIjoiVGVzdE5hbWUifQ.Z_8DKOQiXldAMyJj2BGNzfJd2cTm_XqEcgsAOFyeKwHGJ9yx4uYUM9V7FAUFRPzW7fsb1I2LIS8RDo_riw9m5c8xeequ1noAYbydOZIDHuM9tefplCsve0_cIzek6lV0B0jykDj7OFtJMsDs9TQEtKcjVDGkBK4BnHUwUTLB_lYdzTjMm7WXOpFxz5c74tP5vaER1nuFhtftO5Hsy7jKyRRgdhKJ2o3Do_-LGdEfG9m51dUSb5E8odVGu1vGBQVsc88a11y5uFzORL7cm6hu2RwEELIzfd7bdHruQ9BB5mpS4AGzD4QxtHs2jgYXQ4-HqWFvnpJ-Z89_xWcmo-wOKA", firstActorTokenString); + + var secondActorTokenString = tokenHandler.WriteTokenAsString(actorToken); + + Assert.IsNotNull(secondActorTokenString); + Assert.AreEqual("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjhMcjBkRjJGRC00QXlUbXhzNnh4enRqYUl6WSJ9.eyJhdWQiOiJUZXN0QXVkaWVuY2UiLCJpc3MiOiJUZXN0IElzc3VlciIsIm5iZiI6IjE0ODMyMjUyMDAiLCJleHAiOiIxNTE0NzYxMTk5IiwibmFtZWlkIjoiVGVzdE5hbWUifQ.Z_8DKOQiXldAMyJj2BGNzfJd2cTm_XqEcgsAOFyeKwHGJ9yx4uYUM9V7FAUFRPzW7fsb1I2LIS8RDo_riw9m5c8xeequ1noAYbydOZIDHuM9tefplCsve0_cIzek6lV0B0jykDj7OFtJMsDs9TQEtKcjVDGkBK4BnHUwUTLB_lYdzTjMm7WXOpFxz5c74tP5vaER1nuFhtftO5Hsy7jKyRRgdhKJ2o3Do_-LGdEfG9m51dUSb5E8odVGu1vGBQVsc88a11y5uFzORL7cm6hu2RwEELIzfd7bdHruQ9BB5mpS4AGzD4QxtHs2jgYXQ4-HqWFvnpJ-Z89_xWcmo-wOKA", secondActorTokenString); + + } } } diff --git a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/RSACngProxy.cs b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/RSACngProxy.cs new file mode 100644 index 0000000..c1977ed --- /dev/null +++ b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/RSACngProxy.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.IdentityModel.Extensions.S2S.Tokens +{ + internal sealed class RSACngProxy : System.IDisposable + { + private bool _disposed; + + private bool _disposeRsa; + + private System.Security.Cryptography.RSACng _rsa; + + public RSACngProxy(System.Security.Cryptography.RSACng rsa) + { + Utility.VerifyNonNullArgument("rsa", rsa); + + this._rsa = rsa; + } + + private void Dispose(bool disposing) + { + if (!this._disposed) + { + if (disposing && this._disposeRsa && this._rsa != null) + { + this._rsa.Dispose(); + this._rsa = null; + } + this._disposed = true; + } + } + + public byte[] SignData(byte[] signingInput, HashAlgorithmName hashAlgorithm) + { + var signaturePadding = RSASignaturePadding.Pkcs1; + return this._rsa.SignData(signingInput, hashAlgorithm, signaturePadding); + + } + + public bool VerifyData(byte[] signingInput, HashAlgorithmName hashAlgorithm, byte[] signature) + { + return this._rsa.VerifyData(signingInput, signature, hashAlgorithm, RSASignaturePadding.Pkcs1); + + } + + public void Dispose() + { + this.Dispose(true); + System.GC.SuppressFinalize(this); + } + } +} diff --git a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509RsaCngAsymmetricSignatureProvider.cs b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509RsaCngAsymmetricSignatureProvider.cs index cfe37a9..2a5f02d 100644 --- a/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509RsaCngAsymmetricSignatureProvider.cs +++ b/SharePointPnP.IdentityModel.Extensions/S2S/Tokens/X509RsaCngAsymmetricSignatureProvider.cs @@ -8,7 +8,7 @@ internal class X509RsaCngAsymmetricSignatureProvider : SignatureProvider { private bool _disposed; - private RSACng _rsa; + private RSACngProxy _rsaProxy; private HashAlgorithmName? _hashAlgorithm; @@ -38,10 +38,10 @@ protected override void Dispose(bool disposing) { this._hashAlgorithm = null; } - if (this._rsa != null) + if (this._rsaProxy != null) { - this._rsa.Dispose(); - this._rsa = null; + this._rsaProxy.Dispose(); + this._rsaProxy = null; } } this._disposed = true; @@ -66,7 +66,7 @@ private void Initialize(RSACng rsa) { this._hashAlgorithm = new HashAlgorithmName("SHA256"); } - this._rsa = rsa; + this._rsaProxy = new RSACngProxy(rsa); } public override byte[] Sign(byte[] signingInput) @@ -76,8 +76,7 @@ public override byte[] Sign(byte[] signingInput) { throw new NullReferenceException("Hash algorithm has not been set"); } - var signaturePadding = RSASignaturePadding.Pkcs1; - return this._rsa.SignData(signingInput, this._hashAlgorithm.Value, signaturePadding); + return this._rsaProxy.SignData(signingInput, this._hashAlgorithm.Value); } public override bool Verify(byte[] signingInput, byte[] signature) @@ -88,7 +87,7 @@ public override bool Verify(byte[] signingInput, byte[] signature) { throw new NullReferenceException("Hash algorithm has not been set"); } - return this._rsa.VerifyData(signingInput, signature, this._hashAlgorithm.Value, RSASignaturePadding.Pkcs1); + return this._rsaProxy.VerifyData(signingInput, this._hashAlgorithm.Value, signature); } } }