public void CompareJwkThumbprints(JsonWebKeyConverterTheoryData theoryData)
        {
            var context = TestUtilities.WriteHeader($"{this}.CompareJwkThumbprints", theoryData);

            try
            {
                JsonWebKey convertedKey;
                if (theoryData.SecurityKey is X509SecurityKey x509SecurityKey)
                {
                    convertedKey = JsonWebKeyConverter.ConvertFromX509SecurityKey(x509SecurityKey, true);
                }
                else
                {
                    convertedKey = JsonWebKeyConverter.ConvertFromSecurityKey(theoryData.SecurityKey);
                }

                theoryData.ExpectedException.ProcessNoException(context);
                IdentityComparer.AreBytesEqual(convertedKey.ComputeJwkThumbprint(), theoryData.SecurityKey.ComputeJwkThumbprint(), context);
            }
            catch (Exception ex)
            {
                theoryData.ExpectedException.ProcessException(ex, context);
            }

            TestUtilities.AssertFailIfErrors(context);
        }
Beispiel #2
0
        /// <summary>
        /// Creates a <see cref="JsonWebKey"/> from the passed <see cref="X509Certificate2"/>.
        /// </summary>
        /// <param name="certificate">The certificate.</param>
        /// <param name="use">The key use.</param>
        /// <param name="keyOperations">The key operations</param>
        /// <returns></returns>
        public static JsonWebKey CreateJwk(this X509Certificate2 certificate, string use, params string[] keyOperations)
        {
            JsonWebKey?jwk = null;

            if (certificate.HasPrivateKey)
            {
                var keyAlg = certificate.SignatureAlgorithm.FriendlyName ?? string.Empty;
                if (keyAlg.Contains("RSA"))
                {
                    var rsa        = certificate.GetRSAPrivateKey() !;
                    var parameters = rsa.ExportParameters(true);
                    jwk = new JsonWebKey
                    {
                        Kid = certificate.Thumbprint,
                        Kty = JsonWebAlgorithmsKeyTypes.RSA,
                        //Alg = keyAlg,
                        E  = parameters.Exponent == null ? null : Convert.ToBase64String(parameters.Exponent),
                        N  = parameters.Modulus == null ? null : Convert.ToBase64String(parameters.Modulus),
                        D  = parameters.D == null ? null : Convert.ToBase64String(parameters.D),
                        DP = parameters.DP == null ? null : Convert.ToBase64String(parameters.DP),
                        DQ = parameters.DQ == null ? null : Convert.ToBase64String(parameters.DQ),
                        QI = parameters.Modulus == null ? null : Convert.ToBase64String(parameters.InverseQ !),
                        P  = parameters.Modulus == null ? null : Convert.ToBase64String(parameters.P !),
                        Q  = parameters.Modulus == null ? null : Convert.ToBase64String(parameters.Q !)
                    };
                }
                else if (keyAlg.Contains("ecdsa"))
                {
                    var ecdsa      = certificate.GetECDsaPrivateKey() !;
                    var parameters = ecdsa.ExportParameters(true);
                    jwk = new JsonWebKey
                    {
                        Kty = JsonWebAlgorithmsKeyTypes.EllipticCurve,
                        Alg = keyAlg,
                        D   = parameters.D == null ? null : Convert.ToBase64String(parameters.D),
                        Crv = parameters.Curve.Hash.ToString(),
                        X   = parameters.Q.X?.ToBase64Simplified(),
                        Y   = parameters.Q.Y?.ToBase64Simplified()
                              //Q = parameters.Q == null ? null:Convert.ToBase64String(parameters.Q),
                    };
                }
            }

            jwk ??= JsonWebKeyConverter.ConvertFromX509SecurityKey(new X509SecurityKey(certificate));

            jwk.Use = use;
            jwk.X5t = certificate.Thumbprint;
            jwk.Kid = certificate.Thumbprint;

            foreach (var keyOperation in keyOperations)
            {
                jwk.KeyOps.Add(keyOperation);
            }

            return(jwk);
        }
Beispiel #3
0
        // https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials
        public async Task <string> GetClientAssertionAsync(string tenantId, string appId)
        {
            try
            {
                var cert = await _kvClient.GetCertificateAsync($"https://{_kvName}.vault.azure.net/certificates/func-cred-cert/{_signingKeyId}").ConfigureAwait(false);

                //var thumbprint = cert.X509Thumbprint.Aggregate(new StringBuilder(),
                //               (sb, v) => sb.Append(v.ToString("X2"))).ToString();
                var x509  = new System.Security.Cryptography.X509Certificates.X509Certificate2(cert.Cer);
                var jwk   = JsonWebKeyConverter.ConvertFromX509SecurityKey(new X509SecurityKey(x509));
                var token = new JwtSecurityToken(
                    issuer: appId,
                    audience: $"https://login.microsoftonline.com/{tenantId}/oauth2/token",
                    claims: new Claim[]
                {
                    new Claim("jti", Guid.NewGuid().ToString("D")),
                    new Claim("sub", appId)
                },
                    notBefore: DateTime.UtcNow,
                    expires: DateTime.UtcNow.AddMinutes(10)
                    );
                var header = Base64UrlEncoder.Encode(JsonConvert.SerializeObject(new Dictionary <string, string>()
                {
                    { JwtHeaderParameterNames.Alg, "RS256" },
                    { JwtHeaderParameterNames.X5t, jwk.X5t }, // "CM2UiOQMKph-SkcT5_Ejki2Kzik"; initially, used B2C to get this value; see https://stackoverflow.microsoft.com/questions/179774
                    { JwtHeaderParameterNames.Typ, "JWT" }
                }));

                var unsignedToken = $"{header}.{token.EncodedPayload}";
                var byteData      = Encoding.UTF8.GetBytes(unsignedToken);
                var hasher        = new SHA256CryptoServiceProvider();
                var digest        = hasher.ComputeHash(byteData);
                var signature     = await _kvClient.SignAsync($"https://{_kvName}.vault.azure.net/keys/func-cred-cert/{_signingKeyId}", "RS256", digest);

                return($"{unsignedToken}.{Base64UrlEncoder.Encode(signature.Result)}");
            }
            catch (Exception ex)
            {
                return(ex.Message);
            }
        }
Beispiel #4
0
        public void ConvertX509SecurityKeyAsRsaSecurityKeyToJsonWebKey(JsonWebKeyConverterTheoryData theoryData)
        {
            var context = TestUtilities.WriteHeader($"{this}.ConvertX509SecurityKeyToJsonWebKeyTheoryData", theoryData);

            try
            {
                var convertedKey = JsonWebKeyConverter.ConvertFromX509SecurityKey(theoryData.SecurityKey as X509SecurityKey, theoryData.RepresentAsRsaKey);

                theoryData.ExpectedException.ProcessNoException(context);
                IdentityComparer.AreEqual(convertedKey, theoryData.JsonWebKey, context);

                var expectedConvertedKeyType = theoryData.RepresentAsRsaKey == true ? typeof(RsaSecurityKey) : typeof(X509SecurityKey);
                if (convertedKey.ConvertedSecurityKey.GetType() != expectedConvertedKeyType)
                {
                    context.AddDiff($"convertedKey.ConvertedSecurityKey.GetType(): '{convertedKey.ConvertedSecurityKey.GetType()}' != expectedConvertedKeyType: '{expectedConvertedKeyType}'.");
                }
            }
            catch (Exception ex)
            {
                theoryData.ExpectedException.ProcessException(ex, context);
            }

            TestUtilities.AssertFailIfErrors(context);
        }
        public JwtRequestAuthorizeTests()
        {
            IdentityModelEventSource.ShowPII = true;

            _rsaKey = CryptoHelper.CreateRsaSecurityKey();

            _mockPipeline.Clients.AddRange(new Client[]
            {
                _client = new Client
                {
                    ClientName           = "Client with keys",
                    ClientId             = "client",
                    Enabled              = true,
                    RequireRequestObject = true,

                    RedirectUris = { "https://client/callback" },

                    ClientSecrets =
                    {
                        new Secret
                        {
                            // x509 cert as base64 string
                            Type  = IdentityServerConstants.SecretTypes.X509CertificateBase64,
                            Value = Convert.ToBase64String(TestCert.Load().Export(X509ContentType.Cert))
                        },
                        new Secret
                        {
                            // symmetric key as JWK
                            Type  = IdentityServerConstants.SecretTypes.JsonWebKey,
                            Value = _symmetricJwk
                        },
                        new Secret
                        {
                            // RSA key as JWK
                            Type  = IdentityServerConstants.SecretTypes.JsonWebKey,
                            Value = JsonConvert.SerializeObject(JsonWebKeyConverter.ConvertFromRSASecurityKey(_rsaKey))
                        },
                        new Secret
                        {
                            // x509 cert as JWK
                            Type  = IdentityServerConstants.SecretTypes.JsonWebKey,
                            Value = JsonConvert.SerializeObject(JsonWebKeyConverter.ConvertFromX509SecurityKey(new X509SecurityKey(TestCert.Load())))
                        }
                    },

                    AllowedGrantTypes = GrantTypes.Implicit,

                    AllowedScopes = new List <string>
                    {
                        "openid", "profile", "api1", "api2"
                    }
                },
            });

            _mockPipeline.Users.Add(new TestUser
            {
                SubjectId = "bob",
                Username  = "******",
                Claims    = new Claim[]
                {
                    new Claim("name", "Bob Loblaw"),
                    new Claim("email", "*****@*****.**"),
                    new Claim("role", "Attorney")
                }
            });

            _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email()
            });
            _mockPipeline.ApiScopes.AddRange(new ApiResource[] {
                new ApiResource
                {
                    Name   = "api",
                    Scopes =
                    {
                        new Scope
                        {
                            Name = "api1"
                        },
                        new Scope
                        {
                            Name = "api2"
                        }
                    }
                }
            });

            _mockPipeline.Initialize();
        }
Beispiel #6
0
 public DefaultJwtProvider(IOptions <JwtOptions> options)
 {
     _options   = options.Value;
     JsonWebKey = JsonWebKeyConverter
                  .ConvertFromX509SecurityKey(_options.SecurityKey);
 }