public void JsonWebKeySet_Constructors()
        {
            JsonWebKeySet jsonWebKeys = new JsonWebKeySet();
            Assert.IsTrue(IsDefaultJsonWebKeySet(jsonWebKeys));

            // null string, nothing to add
            RunJsonWebKeySetTest((string)null, null, ExpectedException.ArgumentNullException());

            // null dictionary, nothing to add
            RunJsonWebKeySetTest((IDictionary<string, object>)null, null, ExpectedException.ArgumentNullException(), false);

            RunJsonWebKeySetTest(OpenIdConfigData.JsonWebKeySetString1,  OpenIdConfigData.JsonWebKeySetExpected1, ExpectedException.NoExceptionExpected);
            RunJsonWebKeySetTest(OpenIdConfigData.JsonWebKeySetBadFormatingString, null, ExpectedException.ArgumentException());
        }
        public async Task RefreshMetadataAsync()
        {
            // Get Metadata from endpoint
            var dataTask = HttpApiGet(MetadataEndpoint);

            // Try to get the JSON metadata object
            JObject json;
            try
            {
                json = JObject.Parse(await dataTask);
            }
            catch (JsonReaderException exception)
            {
                // Fail on invalid JSON
                throw new Exception(
                    $"RefreshMetadataAsync: Metadata address returned invalid JSON object ('{MetadataEndpoint}')",
                    exception);
            }

            // Set internal URI properties
            try
            {
                // Preload required data fields
                var jwksEndpoint = new Uri(json[OpenIdProviderMetadataNames.JwksUri].ToString());
                var jwks = new JsonWebKeySet(await HttpApiGet(jwksEndpoint));

                using (new WriterGuard(_metadata.Lock))
                {
                    _metadata.Jwks = jwks;
                    _metadata.JwksEndpoint = jwksEndpoint;
                    _metadata.Issuer = json[OpenIdProviderMetadataNames.Issuer].ToString();
                    _metadata.AuthorizationEndpoint =
                        new Uri(json[OpenIdProviderMetadataNames.AuthorizationEndpoint].ToString());
                    _metadata.TokenEndpoint =
                        new Uri(json[OpenIdProviderMetadataNames.TokenEndpoint].ToString());
                    _metadata.UserInfoEndpoint =
                        new Uri(json[OpenIdProviderMetadataNames.UserInfoEndpoint].ToString());
                    _metadata.EndSessionEndpoint =
                        new Uri(json[OpenIdProviderMetadataNames.EndSessionEndpoint].ToString());

                    // Check for values
                    if (_metadata.AuthorizationEndpoint == null || _metadata.TokenEndpoint == null ||
                        _metadata.UserInfoEndpoint == null)
                    {
                        throw new Exception("One or more metadata endpoints are missing");
                    }
                }

                // Update refresh time
                _nextCachedRefreshTime = DateTime.Now.Add(_options.MetadataRefreshInterval);
            }
            catch (Exception exception)
            {
                // Fail on invalid URI or metadata
                throw new Exception(
                    $"RefreshMetadataAsync: Metadata address returned incomplete data ('{MetadataEndpoint}')", exception);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="compareTo"></param>
        /// <param name="expectedException"></param>
        /// <param name="asString"> this is useful when passing null for parameter 'is' and 'as' don't contain type info.</param>
        /// <returns></returns>
        private JsonWebKeySet RunJsonWebKeySetTest(object obj, JsonWebKeySet compareTo, ExpectedException expectedException, bool asString = true)
        {
            JsonWebKeySet jsonWebKeys = null;
            try
            {
                if (obj is string)
                {
                    jsonWebKeys = new JsonWebKeySet(obj as string);
                }
                else if (obj is IDictionary<string, object>)
                {
                    jsonWebKeys = new JsonWebKeySet(obj as IDictionary<string, object>);
                }
                else
                {
                    if (asString)
                    {
                        jsonWebKeys = new JsonWebKeySet(obj as string);
                    }
                    else
                    {
                        jsonWebKeys = new JsonWebKeySet(obj as IDictionary<string, object>);
                    }
                }
                expectedException.ProcessNoException();
            }
            catch (Exception ex)
            {
                expectedException.ProcessException(ex);
            }

            if (compareTo != null)
            {
                Assert.IsTrue(IdentityComparer.AreEqual<JsonWebKeySet>(jsonWebKeys, compareTo, CompareContext.Default), "jsonWebKeys created from: " + (obj == null ? "NULL" : obj.ToString() + " did not match expected."));
            }

            return jsonWebKeys;
        }
        private bool IsDefaultJsonWebKeySet(JsonWebKeySet jsonWebKeys)
        {
            if (jsonWebKeys.Keys == null)
                return false;

            if (jsonWebKeys.Keys.Count != 0)
                return false;

            return true;
        }
 private void GetSigningTokens(string webKeySetString, List<SecurityToken> expectedTokens, ExpectedException expectedException)
 {
     JsonWebKeySet webKeySet = new JsonWebKeySet(webKeySetString);
     try
     {
         IList<SecurityToken> tokens = webKeySet.GetSigningTokens();
         expectedException.ProcessNoException();
         if (expectedTokens != null)
         {
             Assert.IsTrue(IdentityComparer.AreEqual<IEnumerable<SecurityToken>>(tokens, expectedTokens));
         }
     }
     catch (Exception ex)
     {
         expectedException.ProcessException(ex);
     }
 }
        static OpenIdConfigData()
        {
            JsonWebKeyFromPingExpected1 =
                new JsonWebKey
                {
                    E = "AQAB",
                    Kid = "20am7",
                    Kty = "RSA",
                    N = "mhupHfUtg_gHIqwu2wm8CprXY-gKqbPMV6tEYVqkyYrHugzQ_YDYAHr7vWo5Pe_3gIujSFwpqIfXaP8-Fl3O5fQhMo1lMv4DdRabyDLEpv7YO9qoVKTmDOZqYZx-AYBr5x1Zh2xWByI6_0dsPtCjD1pFZfg_SxNEcLPyH1aY6dT8CWYu32qG4O0WF4EihZzMkzSn8fyh8RXbMf5U9Wm2kgb0g8jK62S7MoF4IlhFaJreq898wgUohhPwR8P3X-gk0XQJAFcogEf04Fw4UmKo3z1B6mcNbPRfImhWw4wtLkhp_KIqKNOkMsSpYGSLrCvqQpgK56EJZExrmb7WozjwHw",
                    Use = "sig"
                };

           JsonWebKeyFromPingExpected2 =
                new JsonWebKey
                {
                    E = "AQAB",
                    Kid = "20am3",
                    Kty = "RSA",
                    N = "wY2KNRyiEvyBFkr1IC_1UGWMPInkzVYpoap_-Zw5fYAXLVxKMSPdZVVLt9AVhuNtagOOQqlZ_Y32e4l19REHym6RGV9Sm1noKRxDUjkz7U8OVeUew7D7h4Dk6E2rrlIYpy9OmhhzWSS68pBTf0_ESdekKv3OQbEs99avEXOPK5uH3V-NHsy1YP3DAvl7HJaV6fn-1Nch1quLrg1G7ohBuTb4Zr-499TJ6bkfabaACz8bf-RHuPezFBjoY0LHNNu6-KQ-qqHVkoki_1OQwj2s_Lui3qYWOmLoaVN9ZzO90rBdhhg8t0JZv6pSlc7o0XT4fie5RRjiqCuOpuGQvNYKpQ",
                    Use = "sig"
                };

           JsonWebKeyFromPingExpected3 =
                new JsonWebKey
                {
                    E = "AQAB",
                    Kid = "20alz",
                    Kty = "RSA",
                    N = "tgLZUXY8mo2Y1TaXHjOYrFGs23jZxgpzEKfBz004AEeOMHFbEP1h1Lrqf2B7f49mOpXRkBgEm4tnSYzX7pDWrMvNeRVkTFXSXwHYvda1R1kmwiTxnrC9IWjvizrr22DtzHhSSpL_7xuXtmaid2orOF8mUoXnKesPQVfq33pCKm1QUV6oFNSVxAiOKJkzFmxjYvcqzryjYi10glxPSx3cmSI8RGqlxolJr0negfLmI9bNxuAvStf_L6zXB5NFqccmkCQXn_QC3P1N3j-HgwwHTVFxkrS8kZQOMTw3TMXbtTFNrVAx1QC_3M0ze4cVncr2zTSECS_2qXM5RS7xBTEDvQ",
                    Use = "sig"
                };

            JsonWebKeyExpected1 =
                new JsonWebKey
                {
                    Alg = "SHA256",
                    E = "AQAB",
                    KeyOps = "signing",
                    Kid = "NGTFvdK-fythEuLwjpwAJOM9n-A",
                    Kty = "RSA",
                    N = "rCz8Sn3GGXmikH2MdTeGY1D711EORX/lVXpr+ecGgqfUWF8MPB07XkYuJ54DAuYT318+2XrzMjOtqkT94VkXmxv6dFGhG8YZ8vNMPd4tdj9c0lpvWQdqXtL1TlFRpD/P6UMEigfN0c9oWDg9U7Ilymgei0UXtf1gtcQbc5sSQU0S4vr9YJp2gLFIGK11Iqg4XSGdcI0QWLLkkC6cBukhVnd6BCYbLjTYy3fNs4DzNdemJlxGl8sLexFytBF6YApvSdus3nFXaMCtBGx16HzkK9ne3lobAwL2o79bP4imEGqg+ibvyNmbrwFGnQrBc1jTF9LyQX9q+louxVfHs6ZiVw==",
                    X5t = "NGTFvdK-fythEuLwjpwAJOM9n-A",
                    X5u = "https://jsonkeyurl",
                    Use = "sig",
                };
            
            JsonWebKeyExpected1.X5c.Add(JsonWebKey_X5c_1);

            JsonWebKeyDictionary1 =
                new Dictionary<string, object>
                {
                    {"alg", "SHA256"},
                    {"e", "AQAB"},
                    {"key_ops", "signing"},
                    {"kid", "NGTFvdK-fythEuLwjpwAJOM9n-A"},
                    {"kty", "RSA"},
                    {"n", "kSCWg6q9iYxvJE2NIhSyOiKvqoWCO2GFipgH0sTSAs5FalHQosk9ZNTztX0ywS/AHsBeQPqYygfYVJL6/EgzVuwRk5txr9e3n1uml94fLyq/AXbwo9yAduf4dCHTP8CWR1dnDR+Qnz/4PYlWVEuuHHONOw/blbfdMjhY+C/BYM2E3pRxbohBb3x//CfueV7ddz2LYiH3wjz0QS/7kjPiNCsXcNyKQEOTkbHFi3mu0u13SQwNddhcynd/GTgWN8A+6SN1r4hzpjFKFLbZnBt77ACSiYx+IHK4Mp+NaVEi5wQtSsjQtI++XsokxRDqYLwus1I1SihgbV/STTg5enufuw=="},                    
                    {"x5c", new ArrayList(new List<string> { "MIIDPjCCAiqgAwIBAgIQVWmXY/+9RqFA/OG9kFulHDAJBgUrDgMCHQUAMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwHhcNMTIwNjA3MDcwMDAwWhcNMTQwNjA3MDcwMDAwWjAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArCz8Sn3GGXmikH2MdTeGY1D711EORX/lVXpr+ecGgqfUWF8MPB07XkYuJ54DAuYT318+2XrzMjOtqkT94VkXmxv6dFGhG8YZ8vNMPd4tdj9c0lpvWQdqXtL1TlFRpD/P6UMEigfN0c9oWDg9U7Ilymgei0UXtf1gtcQbc5sSQU0S4vr9YJp2gLFIGK11Iqg4XSGdcI0QWLLkkC6cBukhVnd6BCYbLjTYy3fNs4DzNdemJlxGl8sLexFytBF6YApvSdus3nFXaMCtBGx16HzkK9ne3lobAwL2o79bP4imEGqg+ibvyNmbrwFGnQrBc1jTF9LyQX9q+louxVfHs6ZiVwIDAQABo2IwYDBeBgNVHQEEVzBVgBCxDDsLd8xkfOLKm4Q/SzjtoS8wLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldIIQVWmXY/+9RqFA/OG9kFulHDAJBgUrDgMCHQUAA4IBAQAkJtxxm/ErgySlNk69+1odTMP8Oy6L0H17z7XGG3w4TqvTUSWaxD4hSFJ0e7mHLQLQD7oV/erACXwSZn2pMoZ89MBDjOMQA+e6QzGB7jmSzPTNmQgMLA8fWCfqPrz6zgH+1F1gNp8hJY57kfeVPBiyjuBmlTEBsBlzolY9dd/55qqfQk6cgSeCbHCy/RU/iep0+UsRMlSgPNNmqhj5gmN2AFVCN96zF694LwuPae5CeR2ZcVknexOWHYjFM0MgUSw0ubnGl0h9AJgGyhvNGcjQqu9vd1xkupFgaN+f7P3p3EVN5csBg5H94jEcQZT7EKeTiZ6bTrpDAnrr8tDCy8ng"})},
                    {"x5t", "NGTFvdK-fythEuLwjpwAJOM9n-A"},
                    {"x5u", "https://jsonkeyurl"},
                    {"use", "sig"},
                };

            JsonWebKeyExpected2 = 
                new JsonWebKey
                {
                    Alg = "SHA256",
                    E = "AQAB",
                    Kid = "kriMPdmBvx68skT8-mPAB3BseeA",
                    Kty = "RSA",
                    N = "kSCWg6q9iYxvJE2NIhSyOiKvqoWCO2GFipgH0sTSAs5FalHQosk9ZNTztX0ywS/AHsBeQPqYygfYVJL6/EgzVuwRk5txr9e3n1uml94fLyq/AXbwo9yAduf4dCHTP8CWR1dnDR+Qnz/4PYlWVEuuHHONOw/blbfdMjhY+C/BYM2E3pRxbohBb3x//CfueV7ddz2LYiH3wjz0QS/7kjPiNCsXcNyKQEOTkbHFi3mu0u13SQwNddhcynd/GTgWN8A+6SN1r4hzpjFKFLbZnBt77ACSiYx+IHK4Mp+NaVEi5wQtSsjQtI++XsokxRDqYLwus1I1SihgbV/STTg5enufuw==",
                    X5t = "kriMPdmBvx68skT8-mPAB3BseeA",
                    Use = "sig",
                };

            JsonWebKeyExpected2.X5c.Add(JsonWebKey_X5c_2);

            JsonWebKeySetExpected1 = new JsonWebKeySet();
            JsonWebKeySetExpected1.Keys.Add(JsonWebKeyExpected1);
            JsonWebKeySetExpected1.Keys.Add(JsonWebKeyExpected2);

            JsonWebKeyExpectedBadX509Data =
                new JsonWebKey
                {
                    Alg = null,
                    KeyOps = null,
                    Kid = "kriMPdmBvx68skT8-mPAB3BseeA",
                    Kty = "RSA",
                    X5t = "kriMPdmBvx68skT8-mPAB3BseeA",
                    X5u = null,
                    Use = "sig"
                };

            JsonWebKeyExpectedBadX509Data.X5c.Add("==MIIDPjCCAiqgAwIBAgIQsRiM0jheFZhKk49YD0SK1TAJBgUrDgMCHQUAMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwHhcNMTQwMTAxMDcwMDAwWhcNMTYwMTAxMDcwMDAwWjAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkSCWg6q9iYxvJE2NIhSyOiKvqoWCO2GFipgH0sTSAs5FalHQosk9ZNTztX0ywS/AHsBeQPqYygfYVJL6/EgzVuwRk5txr9e3n1uml94fLyq/AXbwo9yAduf4dCHTP8CWR1dnDR+Qnz/4PYlWVEuuHHONOw/blbfdMjhY+C/BYM2E3pRxbohBb3x//CfueV7ddz2LYiH3wjz0QS/7kjPiNCsXcNyKQEOTkbHFi3mu0u13SQwNddhcynd/GTgWN8A+6SN1r4hzpjFKFLbZnBt77ACSiYx+IHK4Mp+NaVEi5wQtSsjQtI++XsokxRDqYLwus1I1SihgbV/STTg5enufuwIDAQABo2IwYDBeBgNVHQEEVzBVgBDLebM6bK3BjWGqIBrBNFeNoS8wLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldIIQsRiM0jheFZhKk49YD0SK1TAJBgUrDgMCHQUAA4IBAQCJ4JApryF77EKC4zF5bUaBLQHQ1PNtA1uMDbdNVGKCmSf8M65b8h0NwlIjGGGy/unK8P6jWFdm5IlZ0YPTOgzcRZguXDPj7ajyvlVEQ2K2ICvTYiRQqrOhEhZMSSZsTKXFVwNfW6ADDkN3bvVOVbtpty+nBY5UqnI7xbcoHLZ4wYD251uj5+lo13YLnsVrmQ16NCBYq2nQFNPuNJw6t3XUbwBHXpF46aLT1/eGf/7Xx6iy8yPJX4DyrpFTutDz882RWofGEO5t4Cw+zZg70dJ/hH/ODYRMorfXEW+8uKmXMKmX2wyxMKvfiPbTy5LmAU8Jvjs2tLg4rOBcXWLAIarZ");

            OpenIdConnectConfiguration1 = 
                new OpenIdConnectConfiguration()
                {
                    AuthorizationEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/authorize",
                    CheckSessionIframe = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/checksession",
                    EndSessionEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout",
                    Issuer = "https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/",
                    JwksUri = "JsonWebKeySet.json",
                    TokenEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/token",
                };

            X509CertificateJsonWebKey1 = new X509Certificate2(Convert.FromBase64String("MIIDPjCCAiqgAwIBAgIQVWmXY/+9RqFA/OG9kFulHDAJBgUrDgMCHQUAMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwHhcNMTIwNjA3MDcwMDAwWhcNMTQwNjA3MDcwMDAwWjAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArCz8Sn3GGXmikH2MdTeGY1D711EORX/lVXpr+ecGgqfUWF8MPB07XkYuJ54DAuYT318+2XrzMjOtqkT94VkXmxv6dFGhG8YZ8vNMPd4tdj9c0lpvWQdqXtL1TlFRpD/P6UMEigfN0c9oWDg9U7Ilymgei0UXtf1gtcQbc5sSQU0S4vr9YJp2gLFIGK11Iqg4XSGdcI0QWLLkkC6cBukhVnd6BCYbLjTYy3fNs4DzNdemJlxGl8sLexFytBF6YApvSdus3nFXaMCtBGx16HzkK9ne3lobAwL2o79bP4imEGqg+ibvyNmbrwFGnQrBc1jTF9LyQX9q+louxVfHs6ZiVwIDAQABo2IwYDBeBgNVHQEEVzBVgBCxDDsLd8xkfOLKm4Q/SzjtoS8wLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldIIQVWmXY/+9RqFA/OG9kFulHDAJBgUrDgMCHQUAA4IBAQAkJtxxm/ErgySlNk69+1odTMP8Oy6L0H17z7XGG3w4TqvTUSWaxD4hSFJ0e7mHLQLQD7oV/erACXwSZn2pMoZ89MBDjOMQA+e6QzGB7jmSzPTNmQgMLA8fWCfqPrz6zgH+1F1gNp8hJY57kfeVPBiyjuBmlTEBsBlzolY9dd/55qqfQk6cgSeCbHCy/RU/iep0+UsRMlSgPNNmqhj5gmN2AFVCN96zF694LwuPae5CeR2ZcVknexOWHYjFM0MgUSw0ubnGl0h9AJgGyhvNGcjQqu9vd1xkupFgaN+f7P3p3EVN5csBg5H94jEcQZT7EKeTiZ6bTrpDAnrr8tDCy8ng"));
            X509CertificateJsonWebKey2 = new X509Certificate2(Convert.FromBase64String("MIIDPjCCAiqgAwIBAgIQsRiM0jheFZhKk49YD0SK1TAJBgUrDgMCHQUAMC0xKzApBgNVBAMTImFjY291bnRzLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwHhcNMTQwMTAxMDcwMDAwWhcNMTYwMTAxMDcwMDAwWjAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkSCWg6q9iYxvJE2NIhSyOiKvqoWCO2GFipgH0sTSAs5FalHQosk9ZNTztX0ywS/AHsBeQPqYygfYVJL6/EgzVuwRk5txr9e3n1uml94fLyq/AXbwo9yAduf4dCHTP8CWR1dnDR+Qnz/4PYlWVEuuHHONOw/blbfdMjhY+C/BYM2E3pRxbohBb3x//CfueV7ddz2LYiH3wjz0QS/7kjPiNCsXcNyKQEOTkbHFi3mu0u13SQwNddhcynd/GTgWN8A+6SN1r4hzpjFKFLbZnBt77ACSiYx+IHK4Mp+NaVEi5wQtSsjQtI++XsokxRDqYLwus1I1SihgbV/STTg5enufuwIDAQABo2IwYDBeBgNVHQEEVzBVgBDLebM6bK3BjWGqIBrBNFeNoS8wLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldIIQsRiM0jheFZhKk49YD0SK1TAJBgUrDgMCHQUAA4IBAQCJ4JApryF77EKC4zF5bUaBLQHQ1PNtA1uMDbdNVGKCmSf8M65b8h0NwlIjGGGy/unK8P6jWFdm5IlZ0YPTOgzcRZguXDPj7ajyvlVEQ2K2ICvTYiRQqrOhEhZMSSZsTKXFVwNfW6ADDkN3bvVOVbtpty+nBY5UqnI7xbcoHLZ4wYD251uj5+lo13YLnsVrmQ16NCBYq2nQFNPuNJw6t3XUbwBHXpF46aLT1/eGf/7Xx6iy8yPJX4DyrpFTutDz882RWofGEO5t4Cw+zZg70dJ/hH/ODYRMorfXEW+8uKmXMKmX2wyxMKvfiPbTy5LmAU8Jvjs2tLg4rOBcXWLAIarZ"));

            OpenIdConnectConfigurationWithKeys1 =
                new OpenIdConnectConfiguration()
                {
                    AuthorizationEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/authorize",
                    CheckSessionIframe = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/checksession",
                    EndSessionEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout",
                    Issuer = "https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/",
                    JwksUri = "JsonWebKeySet.json",
                    TokenEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/token",
                };

            RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider();
            RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider();
            RSACryptoServiceProvider rsa3 = new RSACryptoServiceProvider();
            string base64String1 = Convert.ToBase64String(Base64UrlEncoder.DecodeBytes(JsonWebKeyFromPingExpected1.N));
            rsa1.FromXmlString(string.Format(CultureInfo.InvariantCulture, rsaImportTemplate, base64String1, JsonWebKeyFromPingExpected1.E));
            string base64String2 = Convert.ToBase64String(Base64UrlEncoder.DecodeBytes(JsonWebKeyFromPingExpected2.N));
            rsa2.FromXmlString(string.Format(CultureInfo.InvariantCulture, rsaImportTemplate, base64String2, JsonWebKeyFromPingExpected2.E));
            string base64String3 = Convert.ToBase64String(Base64UrlEncoder.DecodeBytes(JsonWebKeyFromPingExpected3.N));
            rsa3.FromXmlString(string.Format(CultureInfo.InvariantCulture, rsaImportTemplate, base64String3, JsonWebKeyFromPingExpected3.E));

            OpenIdConnectConfigurationPing =
                new OpenIdConnectConfiguration()
                {
                    AuthorizationEndpoint = "https://connect-interop.pinglabs.org:9031/as/authorization.oauth2",
                    Issuer = "https://connect-interop.pinglabs.org:9031",
                    TokenEndpoint = "https://connect-interop.pinglabs.org:9031/as/token.oauth2",
                    UserInfoEndpoint = "https://connect-interop.pinglabs.org:9031/idp/userinfo.openid"
                };

            OpenIdConnectConfigurationPingLabsJWKS =
                new OpenIdConnectConfiguration()
                {
                    JwksUri = "PingLabsJWKS.json",
                };

            OpenIdConnectConfigurationPingLabsJWKS.SigningTokens.Add(new NamedKeySecurityToken(JsonWebKeyParameterNames.Kid, JsonWebKeyFromPingExpected1.Kid, new RsaSecurityKey(rsa1)));
            OpenIdConnectConfigurationPingLabsJWKS.SigningTokens.Add(new NamedKeySecurityToken(JsonWebKeyParameterNames.Kid, JsonWebKeyFromPingExpected2.Kid, new RsaSecurityKey(rsa2)));
            OpenIdConnectConfigurationPingLabsJWKS.SigningTokens.Add(new NamedKeySecurityToken(JsonWebKeyParameterNames.Kid, JsonWebKeyFromPingExpected3.Kid, new RsaSecurityKey(rsa3)));


            string n = "ns1cm8RU1hKZILPI6pB5Zoxn9mW2tSS0atV+o9FCn9NyeOktEOj1kEXOeIz0KfnqxgPMF1GpshuZBAhgjkyy2kNGE6Zx50CCJgq6XUatvVVJpMp8/FV18ynPf+/TRlF8V2HO3IVJ0XqRJ9fGA2f5xpOweWsdLYitdHbaDCl6IBNSXo52iNuqWAcB1k7jBlsnlXpuvslhLIzj60dnghAVA4ltS3NlFyw1Tz3pGlZQDt7x83IBHe7DA9bV3aJs1trkm1NzI1HoRS4vOqU3n4fn+DlfAE2vYKNkSi/PjuAX+1YQCq6e5uN/hOeSEqji8SsWC2nk/bMTKPwD67rn3jNC9w==";
            string e = "AQAB";
            string n2 = "kSCWg6q9iYxvJE2NIhSyOiKvqoWCO2GFipgH0sTSAs5FalHQosk9ZNTztX0ywS/AHsBeQPqYygfYVJL6/EgzVuwRk5txr9e3n1uml94fLyq/AXbwo9yAduf4dCHTP8CWR1dnDR+Qnz/4PYlWVEuuHHONOw/blbfdMjhY+C/BYM2E3pRxbohBb3x//CfueV7ddz2LYiH3wjz0QS/7kjPiNCsXcNyKQEOTkbHFi3mu0u13SQwNddhcynd/GTgWN8A+6SN1r4hzpjFKFLbZnBt77ACSiYx+IHK4Mp+NaVEi5wQtSsjQtI++XsokxRDqYLwus1I1SihgbV/STTg5enufuw==";
            string e2 = "AQAB";

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            string xml = string.Format(CultureInfo.InvariantCulture, rsaImportTemplate, n, e);
            rsa.FromXmlString(xml);
            OpenIdConnectConfigurationWithKeys1.SigningTokens.Add(new NamedKeySecurityToken("kid", "NGTFvdK-fythEuLwjpwAJOM9n-A", new RsaSecurityKey(rsa)));

            rsa = new RSACryptoServiceProvider();
            xml = string.Format(CultureInfo.InvariantCulture, rsaImportTemplate, n2, e2);
            rsa.FromXmlString(xml);
            OpenIdConnectConfigurationWithKeys1.SigningTokens.Add(new NamedKeySecurityToken("kid", "kriMPdmBvx68skT8-mPAB3BseeA", new RsaSecurityKey(rsa)));
            OpenIdConnectConfigurationWithKeys1.SigningTokens.Add(new X509SecurityToken(X509CertificateJsonWebKey1));
            OpenIdConnectConfigurationWithKeys1.SigningTokens.Add(new X509SecurityToken(X509CertificateJsonWebKey2));

            OpenIdConnectConfigurationSingleX509Data1 = 
                new OpenIdConnectConfiguration()
                {
                    AuthorizationEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/authorize",
                    CheckSessionIframe = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/checksession",
                    EndSessionEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/logout",
                    Issuer = "https://sts.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/",
                    JwksUri = "JsonWebKeySetSingleX509Data.json",
                    TokenEndpoint = "https://login.windows.net/d062b2b0-9aca-4ff7-b32a-ba47231a4002/oauth2/token",
            };

            OpenIdConnectConfigurationSingleX509Data1.SigningTokens.Add(new X509SecurityToken(X509CertificateJsonWebKey1));

            // interrop
            GoogleCertsExpected = new JsonWebKeySet();
            GoogleCertsExpected.Keys.Add(
                new JsonWebKey
                {
                    Alg = "RS256",
                    E = "AQAB",
                    Kty = "RSA",
                    Kid = "ab844f3d4c69feee0de2501b04e1a4c8d78eead1",
                    N = "AKrMiv5vhYehVKXnSpZZN6lYymUIi+NS97ceYKYClMlNyj2Ln4ErWiOwjwdivG2kZnN0kKCC/XL9E+uEgsZO3ECvvDtgtFhPOR0MiqL7pp/K7d58dbKUWX/cWy8E4bm/Zmwa/g0HDcW6o19+Q85IPYXbY/6Z2oOgA9qDAoGHkjIv",
                    Use = "sig",
                });

           GoogleCertsExpected.Keys.Add(
                new JsonWebKey
                {
                    Alg = "RS256",
                    E = "AQAB",
                    Kty = "RSA",
                    Kid = "550326e0aacb4674d22905a1a51a808cfa7463b0",
                    N = "ANLFuJO6EoKczde+YP3b1yuz2b46D7Rd7CjrbvKrzbjkH29iRFLBagT7nojwdMOPrsV+WLp/C8lfkRT7UJ38lnQh3m4oEy98HdRRMZh5Vtpbotgt4S/ugh5ansJdHSXSBTxk+X1ZnTzMOUH7ZROpxw3NcX/IFl0sshFlTbebPrDj",
                    Use = "sig",
                });

        }
Exemplo n.º 7
0
        private void ValidateTokenAndSignin(JObject payload)
        {
            //Get the key set from http://localhost:62733/.well-known/jwks
            var jsonString =
                "{\"keys\":[{\"kty\":\"RSA\",\"alg\":\"RS256\"," +
                "\"use\":\"sig\",\"x5t\":\"BSxeQhXNDB4VBeCOavOtvvv9eCI\"," +
                "\"x5c\":[\"MIIDPjCCAiqgAwIBAgIQlLEp+P+WKYtEAemhSKSUTTAJBgUrDgMCHQUAMC0xKzApBgNVBAMTIk93aW4uU2VjdXJpdHkuT3BlbklkQ29ubmVjdC5TZXJ2ZXIwHhcNOTkxMjMxMjIwMDAwWhcNNDkxMjMxMjIwMDAwWjAtMSswKQYDVQQDEyJPd2luLlNlY3VyaXR5Lk9wZW5JZENvbm5lY3QuU2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwD/4uMNSIu+JlPRrtFR8Tm2LAwSOmglvJai6edFrdvDvk6xWzxYkMoIt4v13lFiIAUfI1vyZ1M0hWQfrifyweuzZu06DyWTUZkp9ervhTxK27HFN7XTuaRxHaXLR4KnhA+Nk8bBXN895OZh9g9Hf5+zsHpe17zgikwcyZtF+9OEG16oz7lKRgXGCIeeVZuSZ5Qf4yePwKMZqsx+lTOiZJ3JMs+gytvIpdZ1NWzcMX0XTcVTgvnBeU0O3NR6DQ41+SrGsojk11bd6kP6mVmDkA0K9kc2eh7q1wyJOeTNuCKRqLthwJ5m46/KRsxgY7ND6qHc1L60SqsFlYCJNEy7EdwIDAQABo2IwYDBeBgNVHQEEVzBVgBDQX+HKPiztLNvT3jQeBXqToS8wLTErMCkGA1UEAxMiT3dpbi5TZWN1cml0eS5PcGVuSWRDb25uZWN0LlNlcnZlcoIQlLEp+P+WKYtEAemhSKSUTTAJBgUrDgMCHQUAA4IBAQCxbCF5thB+ypGpudLAjv+l3M2VhNITJeR9j7jMlCSMVHvW7iMOL5W++zKvHMMAWuITLgPXTZ4ktsjeVQxWdnS2IcU7SwB9SeLbOMk4lLizoUevkiNaf6v+Hskm5LiH6+k8Zsl0INHyIjF9XlALTh91EqQ820cotDXaQIhHabQy892+dBmGWhSE1kP56IvOPzlLdSTkrcfcOu9gzwPVfuTDWH8Hrmo3FXz/fADmE7ea+yE1ZBeKhaN8kaFTs5zrprJ1BnmegnrjDY3RFgqcTTetahv0VBS0/jHSTIsAXflEPGW7LbHimzcgMytFU4fFtPVbek5eunakhu/JdENbbVmT\"]}]}";


            var jsonWebKeySet = new JsonWebKeySet(jsonString);

            var parameters = new TokenValidationParameters
            {
                ValidAudience = Clients.Client3.Id,
                ValidIssuer = "http://localhost:62733",
                IssuerSigningToken = jsonWebKeySet.GetSigningTokens().First()
            };

            /**
             * This is example of loading  signing public key explicityl
             *        //SigningToken = new X509SecurityToken(
                //   X509
                //   .LocalMachine
                //   .TrustedPeople
                //   .SubjectDistinguishedName
                //   .Find("CN=idsrv3test", false)
                //   .First())
             * **/
            var idToken = payload.SelectToken("id_token").ToString();
            var accessToken = payload.SelectToken("access_token").ToString();
            var refreshToken = payload.SelectToken("refresh_token").ToString();
            long expiresIn = 0; //seconds

            long.TryParse(payload.SelectToken("expires_in").ToString(), out expiresIn);

            SecurityToken jwt;
            var id = new JwtSecurityTokenHandler().ValidateToken(idToken, parameters, out jwt);
            
            var claims = new List<Claim>(from c in id.Claims
                                         where c.Type != "iss" &&
                                               c.Type != "aud" &&
                                               c.Type != "nbf" &&
                                               c.Type != "exp" &&
                                               c.Type != "iat" &&
                                               c.Type != "amr" &&
                                               c.Type != "idp" &&
                                               c.Type != "nonce"
                                         select c);


            if (!string.IsNullOrWhiteSpace(accessToken))
            {
                claims.Add(new Claim("access_token", accessToken));
               // claims.Add(new Claim("expires_at", (DateTime.UtcNow + expiresIn).ToDateTimeFromEpoch().ToString()));
            }
            
            if (!string.IsNullOrWhiteSpace(refreshToken))
            {
                claims.Add(new Claim("refresh_token", refreshToken));
            }

            if (!string.IsNullOrWhiteSpace(idToken))
            {
                claims.Add(new Claim("id_token",idToken));
            }
            

            var newid = new ClaimsIdentity(claims, "CodeClientCookie");
            Request.GetOwinContext().Authentication.SignIn(newid);
        }