Exemplo n.º 1
0
        private static string GetSignedClientAssertionUsingMsalInternal(string clientId, IDictionary <string, string> claims)
        {
#if NET_CORE
            var manager = new Client.Platforms.netcore.NetCoreCryptographyManager();
#else
            var manager = new Client.Platforms.net45.NetDesktopCryptographyManager();
#endif
            var jwtToken         = new Client.Internal.JsonWebToken(manager, clientId, TestConstants.ClientCredentialAudience, claims);
            var clientCredential = ClientCredentialWrapper.CreateWithCertificate(GetCertificate(), claims);
            return(jwtToken.Sign(clientCredential, false));
        }
Exemplo n.º 2
0
        public void CCACreatedWithAuthenticationType_SignedClientAssertion_DoesNotThrow()
        {
            // Arrange
            ApplicationConfiguration config = new ApplicationConfiguration
            {
                SignedClientAssertion = "signed"
            };

            // Act
            ClientCredentialWrapper clientCredentialWrapper = new ClientCredentialWrapper(config);

            // Assert
            // no exception is thrown
            Assert.AreEqual(
                ConfidentialClientAuthenticationType.SignedClientAssertion,
                clientCredentialWrapper.AuthenticationType);
        }
Exemplo n.º 3
0
        public void CCACreatedWithAuthenticationType_ClientSecret_DoesNotThrow()
        {
            // Arrange
            ApplicationConfiguration config = new ApplicationConfiguration
            {
                ClientSecret = TestConstants.ClientSecret
            };

            // Act
            ClientCredentialWrapper clientCredentialWrapper = new ClientCredentialWrapper(config);

            // Assert
            // no exception is thrown
            Assert.AreEqual(
                ConfidentialClientAuthenticationType.ClientSecret,
                clientCredentialWrapper.AuthenticationType);
        }
Exemplo n.º 4
0
        public void ClientAssertionRequestValidatorExpirationTimeTest()
        {
            var credential = ClientCredentialWrapper.CreateWithSecret(TestConstants.ClientSecret);

            credential.Audience        = _audience1;
            credential.ContainsX5C     = false;
            credential.CachedAssertion = TestConstants.DefaultClientAssertion;
            credential.ValidTo         = ConvertToTimeT(DateTime.UtcNow + TimeSpan.FromSeconds(JwtToAadLifetimeInSeconds));

            // Validate cached client assertion with expiration time
            // Cached assertion should be valid
            Assert.IsTrue(ClientCredentialHelper.ValidateClientAssertion(credential, _audience1, false));

            // Setting expiration time to now
            credential.ValidTo = ConvertToTimeT(DateTime.UtcNow);

            // cached assertion should have expired
            Assert.IsFalse(ClientCredentialHelper.ValidateClientAssertion(credential, _audience1, false));
        }
Exemplo n.º 5
0
        public void CCACreatedWithAuthenticationType_ClientCertificate_DoesNotThrow()
        {
            // Arrange
            var cert = new X509Certificate2(
                ResourceHelper.GetTestResourceRelativePath("testCert.crtfile"), "passw0rd!");
            ApplicationConfiguration config = new ApplicationConfiguration
            {
                ClientCredentialCertificate = cert
            };

            // Act
            ClientCredentialWrapper clientCredentialWrapper = new ClientCredentialWrapper(config);

            // Assert
            // no exception is thrown
            Assert.AreEqual(
                ConfidentialClientAuthenticationType.ClientCertificate,
                clientCredentialWrapper.AuthenticationType);
        }
Exemplo n.º 6
0
        public void ClientAssertionRequestValidatorExpirationTimeTest()
        {
            var credential = new ClientCredentialWrapper(MsalTestConstants.ClientSecret)
            {
                Audience    = "Audience1",
                ContainsX5C = false,
                Assertion   = MsalTestConstants.DefaultClientAssertion,
                ValidTo     = ConvertToTimeT(DateTime.UtcNow + TimeSpan.FromSeconds(JwtToAadLifetimeInSeconds))
            };

            // Validate cached client assertion with expiration time
            // Cached assertion should be valid
            Assert.IsTrue(ClientCredentialHelper.ValidateClientAssertion(credential, new AuthorityEndpoints(null, null, "Audience1"), false));

            // Setting expiration time to now
            credential.ValidTo = ConvertToTimeT(DateTime.UtcNow);

            // cached assertion should have expired
            Assert.IsFalse(ClientCredentialHelper.ValidateClientAssertion(credential, new AuthorityEndpoints(null, null, "Audience1"), false));
        }
Exemplo n.º 7
0
        public static Dictionary <string, string> CreateClientCredentialBodyParameters(
            ICoreLogger logger,
            ICryptographyManager cryptographyManager,
            ClientCredentialWrapper clientCredential,
            string clientId,
            AuthorityEndpoints endpoints,
            bool sendX5C)
        {
            Dictionary <string, string> parameters = new Dictionary <string, string>();

            if (clientCredential != null)
            {
                if (!string.IsNullOrEmpty(clientCredential.Secret))
                {
                    parameters[OAuth2Parameter.ClientSecret] = clientCredential.Secret;
                }
                else
                {
                    if (clientCredential.Assertion == null || clientCredential.ValidTo != 0)
                    {
                        if (!ValidateClientAssertion(clientCredential, endpoints, sendX5C))
                        {
                            logger.Info("Client Assertion does not exist or near expiry.");
                            var jwtToken = new JsonWebToken(cryptographyManager, clientId, endpoints?.SelfSignedJwtAudience);
                            clientCredential.Assertion   = jwtToken.Sign(clientCredential.Certificate, sendX5C);
                            clientCredential.ValidTo     = jwtToken.Payload.ValidTo;
                            clientCredential.ContainsX5C = sendX5C;
                            clientCredential.Audience    = endpoints?.SelfSignedJwtAudience;
                        }
                        else
                        {
                            logger.Info("Reusing the unexpired Client Assertion...");
                        }
                    }

                    parameters[OAuth2Parameter.ClientAssertionType] = OAuth2AssertionType.JwtBearer;
                    parameters[OAuth2Parameter.ClientAssertion]     = clientCredential.Assertion;
                }
            }
            return(parameters);
        }
Exemplo n.º 8
0
        public void ClientAssertionRequestValidatorMismatchParameterTest()
        {
            string Audience1 = "Audience1";
            string Audience2 = "Audience2";

            var credential = new ClientCredentialWrapper(MsalTestConstants.ClientSecret)
            {
                Audience    = Audience1,
                ContainsX5C = false,
                Assertion   = MsalTestConstants.DefaultClientAssertion,
                ValidTo     = ConvertToTimeT(DateTime.UtcNow + TimeSpan.FromSeconds(JwtToAadLifetimeInSeconds))
            };

            // Validate cached client assertion with parameters
            Assert.IsTrue(ClientCredentialHelper.ValidateClientAssertion(credential, new AuthorityEndpoints(null, null, Audience1), false));

            // Different audience
            credential.Audience = Audience2;

            // cached assertion should be invalid
            Assert.IsFalse(ClientCredentialHelper.ValidateClientAssertion(credential, new AuthorityEndpoints(null, null, Audience1), false));

            // Different x5c, same audience
            credential.Audience    = Audience1;
            credential.ContainsX5C = true;

            // cached assertion should be invalid
            Assert.IsFalse(ClientCredentialHelper.ValidateClientAssertion(credential, new AuthorityEndpoints(null, null, Audience1), false));

            // Different audience and x5c
            credential.Audience = Audience2;

            // cached assertion should be invalid
            Assert.IsFalse(ClientCredentialHelper.ValidateClientAssertion(credential, new AuthorityEndpoints(null, null, Audience1), false));

            // No cached Assertion
            credential.Assertion = "";

            // should return false
            Assert.IsFalse(ClientCredentialHelper.ValidateClientAssertion(credential, new AuthorityEndpoints(null, null, Audience1), false));
        }
        public void Serialize_Jwt()
        {
            var payload = new JWTPayload
            {
                Audience      = "aud",
                Issuer        = "iss",
                ValidFrom     = 123,
                ValidTo       = 124,
                Subject       = "123-456-789",
                JwtIdentifier = "321-654"
            };

            var certificate = new X509Certificate2(
                ResourceHelper.GetTestResourceRelativePath("RSATestCertDotNet.pfx"));

            var    header        = new JWTHeaderWithCertificate(ClientCredentialWrapper.CreateWithCertificate(certificate), true);
            string actualPayload = JsonHelper.SerializeToJson(payload);
            string actualHeader  = JsonHelper.SerializeToJson(header);

            string expectedPayload = @"{
                                       ""aud"": ""aud"",
                                       ""exp"": 124,
                                       ""iss"": ""iss"",
                                       ""jti"": ""321-654"",
                                       ""nbf"": 123,
                                       ""sub"": ""123-456-789""
                                    }";

            string expectedHeader = @"{
                                       ""alg"": ""RS256"",
                                       ""typ"": ""JWT"",
                                       ""x5t"": ""lJjBuRyk8s_-oQxT3MgwH5qNS94"",
                                       ""kid"": ""9498C1B91CA4F2CFFEA10C53DCC8301F9A8D4BDE"",
                                       ""x5c"": ""MIIDJDCCAgygAwIBAgIQK4SCZgh/R5anP05v4z6VLjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRUZXN0MB4XDTE5MDgxNTE3MjY1M1oXDTIwMDgxNTE3MzY1M1owDzENMAsGA1UEAxMEVGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIxSuzLrpxnq44CSux3l2UMvIBwBXnh4tmmZtju4qCNJzVmCrhyC9i5jH7YCicXeFQChWfbZpyo2TpDD/cTw+Rpi9QLhhGvDnMF+uk1pqSp5Fdh11YacX7w76Wc7Er+FM2PiKtyDX6+nFzUvV3SfjfdcAadConDAWOdmpd34UNZ/DzM6dRKynWuaE+0kD843Tr+pCXlMGQBAQatWyROK+rgOKhnv1/vMAZ90SCjxAhnjxj+9GRIGYzonuTa+EOqXRn1XQ+j54Ux953Oq0zGCNbXndGjGKH1U1JP/nAemFsh0h2DcdAdEkxOS3+QrdiZEkPPfe8x5BLJmvoRWJ9eCAT0CAwEAAaN8MHowDgYDVR0PAQH/BAQDAgWgMAkGA1UdEwQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB8GA1UdIwQYMBaAFB03ltXqrZeIzolZQj8w98DG8HCIMB0GA1UdDgQWBBQdN5bV6q2XiM6JWUI/MPfAxvBwiDANBgkqhkiG9w0BAQsFAAOCAQEAiXAQHHWiJ+8wLk0evDZSXDfQ0brYsKLimxJSrVOzpz4BnHTIr86ZEYA6jCKNfhRnrPU9HQ43CUSU1MRX03ovdJMoYjuWCGAFlZrYMC9PhPwt2B0a3DRl0wsl3jxOYYrFHonBWvjDFdWEP2Nr2T8iWPgpS5uIdgU1GqN9EbI+3B46qH4rTH3vAwpeF38XDjBO8DYycotwG34zgD2zQ2ZoPmQG07Y8rjBo+JW56ri3RfeMu3kZVfM359JXzQhw+L8PDY8MVhltiZ1ufvKS6F5vAZYLUXUGtVmlS7mLgNJKvJN9fxd1BlZdqfD3+o4xBUGVCjS3HR/7NJBl/pPHZtKckQ==""
                                    }";

            JsonTestUtils.AssertJsonDeepEquals(expectedPayload, actualPayload);
            JsonTestUtils.AssertJsonDeepEquals(expectedHeader, actualHeader);
        }
Exemplo n.º 10
0
        /// <summary>
        ///     Determines whether or not the cached client assertion can be used again for the next authentication request by
        ///     checking it's
        ///     values against incoming request parameters.
        /// </summary>
        /// <returns>Returns true if the previously cached client assertion is valid</returns>
        public static bool ValidateClientAssertion(ClientCredentialWrapper clientCredential, AuthorityEndpoints endpoints, bool sendX5C)
        {
            if (clientCredential == null)
            {
                throw new ArgumentNullException(nameof(clientCredential));
            }
            else if (string.IsNullOrWhiteSpace(clientCredential.Assertion))
            {
                return(false);
            }

            //Check if all current client assertion values match incoming parameters and expiration time
            //The clientCredential object contains the previously used values in the cached client assertion string
            bool expired = clientCredential.ValidTo <=
                           JsonWebToken.ConvertToTimeT(
                DateTime.UtcNow + TimeSpan.FromMinutes(Constants.ExpirationMarginInMinutes));

            bool parametersMatch = clientCredential.Audience == endpoints?.SelfSignedJwtAudience &&
                                   clientCredential.ContainsX5C == sendX5C;

            return(!expired && parametersMatch);
        }
        /// <summary>
        ///     Determines whether or not the cached client assertion can be used again for the next authentication request by
        ///     checking its values against incoming request parameters.
        /// </summary>
        /// <returns>Returns true if the previously cached client assertion is valid</returns>
        public static bool ValidateClientAssertion(ClientCredentialWrapper clientCredential, string audience, bool sendX5C)
        {
            if (clientCredential == null)
            {
                throw new ArgumentNullException(nameof(clientCredential));
            }

            if (string.IsNullOrWhiteSpace(clientCredential.CachedAssertion))
            {
                return(false);
            }

            //Check if all current client assertion values match incoming parameters and expiration time
            //The clientCredential object contains the previously used values in the cached client assertion string
            bool expired = clientCredential.ValidTo <=
                           JsonWebToken.ConvertToTimeT(
                DateTime.UtcNow + TimeSpan.FromMinutes(Constants.ExpirationMarginInMinutes));

            bool parametersMatch = string.Equals(clientCredential.Audience, audience, StringComparison.OrdinalIgnoreCase) &&
                                   clientCredential.ContainsX5C == sendX5C;

            return(!expired && parametersMatch);
        }
Exemplo n.º 12
0
        public void ClientAssertionRequestValidatorMismatchParameterTest()
        {
            var credential = ClientCredentialWrapper.CreateWithSecret(TestConstants.ClientSecret);

            credential.Audience        = _audience1;
            credential.ContainsX5C     = false;
            credential.CachedAssertion = TestConstants.DefaultClientAssertion;
            credential.ValidTo         = ConvertToTimeT(DateTime.UtcNow + TimeSpan.FromSeconds(JwtToAadLifetimeInSeconds));

            // Validate cached client assertion with parameters
            Assert.IsTrue(ClientCredentialHelper.ValidateClientAssertion(credential, _audience1, false));

            // Different audience
            credential.Audience = _audience2;

            // cached assertion should be invalid
            Assert.IsFalse(ClientCredentialHelper.ValidateClientAssertion(credential, _audience1, false));

            // Different x5c, same audience
            credential.Audience    = _audience1;
            credential.ContainsX5C = true;

            // cached assertion should be invalid
            Assert.IsFalse(ClientCredentialHelper.ValidateClientAssertion(credential, _audience1, false));

            // Different audience and x5c
            credential.Audience = _audience2;

            // cached assertion should be invalid
            Assert.IsFalse(ClientCredentialHelper.ValidateClientAssertion(credential, _audience1, false));

            // No cached Assertion
            credential.CachedAssertion = "";

            // should return false
            Assert.IsFalse(ClientCredentialHelper.ValidateClientAssertion(credential, _audience1, false));
        }
Exemplo n.º 13
0
        public void CCACreatedWithAuthenticationType_ClientCertificateWithClaims_DoesNotThrow()
        {
            // Arrange
            var cert = new X509Certificate2(
                ResourceHelper.GetTestResourceRelativePath("testCert.crtfile"), "passw0rd!");
            var claims = new Dictionary <string, string>();

            claims.Add("cats", "are cool");

            ApplicationConfiguration config = new ApplicationConfiguration
            {
                ClientCredentialCertificate = cert,
                ClaimsToSign = claims
            };

            // Act
            ClientCredentialWrapper clientCredentialWrapper = new ClientCredentialWrapper(config);

            // Assert
            // no exception is thrown
            Assert.AreEqual(
                ConfidentialClientAuthenticationType.ClientCertificateWithClaims,
                clientCredentialWrapper.AuthenticationType);
        }
        public static Dictionary <string, string> CreateClientCredentialBodyParameters(
            ICoreLogger logger,
            ICryptographyManager cryptographyManager,
            ClientCredentialWrapper clientCredential,
            string clientId,
            AuthorityEndpoints endpoints,
            bool sendX5C)
        {
            Dictionary <string, string> parameters = new Dictionary <string, string>();

            if (clientCredential != null)
            {
                if (clientCredential.AuthenticationType == ConfidentialClientAuthenticationType.ClientSecret)
                {
                    parameters[OAuth2Parameter.ClientSecret] = clientCredential.Secret;
                }
                else
                {
                    if ((clientCredential.CachedAssertion == null || clientCredential.ValidTo != 0) &&
                        clientCredential.AuthenticationType != ConfidentialClientAuthenticationType.SignedClientAssertion &&
                        clientCredential.AuthenticationType != ConfidentialClientAuthenticationType.SignedClientAssertionDelegate)
                    {
                        if (!ValidateClientAssertion(clientCredential, endpoints.SelfSignedJwtAudience, sendX5C))
                        {
                            logger.Info(LogMessages.ClientAssertionDoesNotExistOrNearExpiry);

                            JsonWebToken jwtToken;

                            if (clientCredential.AuthenticationType == ConfidentialClientAuthenticationType.ClientCertificateWithClaims)
                            {
                                jwtToken = new JsonWebToken(cryptographyManager, clientId, endpoints.SelfSignedJwtAudience, clientCredential.ClaimsToSign, clientCredential.AppendDefaultClaims);
                            }
                            else
                            {
                                jwtToken = new JsonWebToken(cryptographyManager, clientId, endpoints.SelfSignedJwtAudience);
                            }

                            clientCredential.CachedAssertion = jwtToken.Sign(clientCredential, sendX5C);
                            clientCredential.ValidTo         = jwtToken.ValidTo;
                            clientCredential.ContainsX5C     = sendX5C;
                            clientCredential.Audience        = endpoints.SelfSignedJwtAudience;
                        }
                        else
                        {
                            logger.Info(LogMessages.ReusingTheUnexpiredClientAssertion);
                        }
                    }

                    parameters[OAuth2Parameter.ClientAssertionType] = OAuth2AssertionType.JwtBearer;

                    if (clientCredential.AuthenticationType == ConfidentialClientAuthenticationType.SignedClientAssertion)
                    {
                        parameters[OAuth2Parameter.ClientAssertion] = clientCredential.SignedAssertion;
                    }
                    else if (clientCredential.AuthenticationType == ConfidentialClientAuthenticationType.SignedClientAssertionDelegate)
                    {
                        parameters[OAuth2Parameter.ClientAssertion] = clientCredential.SignedAssertionDelegate();
                    }
                    else
                    {
                        parameters[OAuth2Parameter.ClientAssertion] = clientCredential.CachedAssertion;
                    }
                }
            }
            return(parameters);
        }