Exemple #1
0
        public void ValidateAuthState_InvalidState(long timestamp, string redirectUrl, long identityProviderId, long tenantId, string nonce)
        {
            var mockRepo         = new MockRepository(MockBehavior.Loose);
            var configManager    = mockRepo.Create <IOpenIdConnectConfigurationManager>();
            var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object);

            // Create invalid auth state
            var authState = new OpenIdConnectAuthorizationState
            {
                Timestamp          = timestamp,
                RedirectUrl        = redirectUrl,
                IdentityProviderId = identityProviderId,
                TenantId           = tenantId,
                Nonce = nonce
            };

            // Serialize and encrypt state
            var stateJson      = JSON.Serialize(authState);
            var cryptoProvider = new EncodingCryptoProvider();
            var encryptedState = cryptoProvider.EncryptAndEncode(stateJson);

            Assert.That(
                () =>
                oidcLoginHandler.ValidateAuthState(encryptedState),
                Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The authorization state has invalid data."));
        }
        public void EncodeDecodeData()
        {
            var cryptoProvider = new EncodingCryptoProvider();

            string encodedCipherText = cryptoProvider.EncryptAndEncode(TestData);

            Assert.AreEqual(TestData, cryptoProvider.DecodeAndDecrypt(encodedCipherText));
        }
        public void EncryptEncodeSameDataGeneratesDifferentCipherText()
        {
            var cryptoProvider = new EncodingCryptoProvider();

            string encodedCipherText1 = cryptoProvider.EncryptAndEncode(TestData);
            string encodedCipherText2 = cryptoProvider.EncryptAndEncode(TestData);

            Assert.AreNotEqual(encodedCipherText1, encodedCipherText2, "The encoded cipher texts should not be equal");
        }
Exemple #4
0
        public void Upgrade()
        {
            var crypto = new EncodingCryptoProvider();

            SecuredDataTestHelper.TestUpgrade(
                TenantEmailSetting.TenantEmailSetting_Type,
                TenantEmailSetting.SmtpPassword_Field.As <Field>(),
                TenantEmailSetting.SmtpPasswordSecureId_Field.As <Field>(),
                (s) => crypto.EncryptAndEncode(s)
                );
        }
        public void Upgrade()
        {
            var crypto = new EncodingCryptoProvider();

            SecuredDataTestHelper.TestUpgrade(
                OidcIdentityProvider.OidcIdentityProvider_Type,
                OidcIdentityProvider.OidcClientSecret_Field.As <Field>(),
                OidcIdentityProvider.OidcClientSecretSecureId_Field.As <Field>(),
                (s) => crypto.EncryptAndEncode(s)
                );
        }
        public void Upgrade()
        {
            var crypto = new EncodingCryptoProvider();

            SecuredDataTestHelper.TestUpgrade(
                ImapServerSettings.ImapServerSettings_Type,
                ImapServerSettings.ImapPassword_Field.As <Field>(),
                ImapServerSettings.ImapPasswordSecureId_Field.As <Field>(),
                (s) => crypto.EncryptAndEncode(s)
                );
        }
Exemple #7
0
        public void ValidateAuthState_ExpiredState()
        {
            var mockRepo         = new MockRepository(MockBehavior.Loose);
            var configManager    = mockRepo.Create <IOpenIdConnectConfigurationManager>();
            var oidcLoginHandler = new OpenIdConnectLoginHandler(configManager.Object);

            // Create invalid auth state
            var authState = new OpenIdConnectAuthorizationState
            {
                Timestamp          = DateTime.UtcNow.AddHours(10).Ticks,
                RedirectUrl        = "http://test.com",
                IdentityProviderId = 100,
                TenantId           = 100,
                Nonce = "xx"
            };

            // Serialize and encrypt state
            var stateJson       = JSON.Serialize(authState);
            var cryptoProvider  = new EncodingCryptoProvider();
            var encryptedState1 = cryptoProvider.EncryptAndEncode(stateJson);

            Assert.That(
                () =>
                oidcLoginHandler.ValidateAuthState(encryptedState1),
                Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The authorization state has expired."));

            // Create invalid auth state
            authState = new OpenIdConnectAuthorizationState
            {
                Timestamp          = DateTime.UtcNow.AddHours(-10).Ticks,
                RedirectUrl        = "http://test.com",
                IdentityProviderId = 100,
                TenantId           = 100,
                Nonce = "xx"
            };

            // Serialize and encrypt state
            stateJson      = JSON.Serialize(authState);
            cryptoProvider = new EncodingCryptoProvider();
            var encryptedState2 = cryptoProvider.EncryptAndEncode(stateJson);

            Assert.That(
                () =>
                oidcLoginHandler.ValidateAuthState(encryptedState2),
                Throws.TypeOf <AuthenticationException>().And.Message.EqualTo("The authorization state has expired."));
        }
Exemple #8
0
        /// <summary>
        /// Called after upgrade.
        /// </summary>
        public static void Upgrade(string tenantName)
        {
            using (new SecurityBypassContext())
            {
                var crypto = new EncodingCryptoProvider();

                using (new GlobalAdministratorContext())
                {
                    /*
                     * ImapServerSettings has been moved to the global tenant only. Not sure if we need to move this elsewhere as here it will be run for each tenant
                     */
                    Factory.SecuredDataSaveHelper.UpgradeField(
                        ImapServerSettingsEventTarget.SecureIdContext,
                        ImapServerSettings.ImapServerSettings_Type,
                        ImapServerSettings.ImapPassword_Field,
                        ImapServerSettings.ImapPasswordSecureId_Field,
                        (s) => crypto.DecodeAndDecrypt(s));
                }
                using (new TenantAdministratorContext(tenantName))
                {
                    Factory.SecuredDataSaveHelper.UpgradeField(
                        EmailServerSettingsEventTarget.SecureIdContext,
                        TenantEmailSetting.TenantEmailSetting_Type,
                        TenantEmailSetting.SmtpPassword_Field,
                        TenantEmailSetting.SmtpPasswordSecureId_Field,
                        (s) => crypto.DecodeAndDecrypt(s));

                    // identityProvider OidcClientSecret
                    Factory.SecuredDataSaveHelper.UpgradeField(
                        OidcIdentityProviderEventTarget.SecureIdContext,
                        OidcIdentityProvider.OidcIdentityProvider_Type,
                        OidcIdentityProvider.OidcClientSecret_Field,
                        OidcIdentityProvider.OidcClientSecretSecureId_Field,
                        (s) => crypto.DecodeAndDecrypt(s)
                        );
                }
            }
        }
        /// <summary>
        ///     Validates the state of the authentication.
        /// </summary>
        /// <param name="state">The state.</param>
        /// <returns>OpenIdConnectAuthorizationState.</returns>
        /// <exception cref="System.ArgumentNullException">state</exception>
        /// <exception cref="AuthenticationException">The authorization state is invalid.</exception>
        public OpenIdConnectAuthorizationState ValidateAuthState(string state)
        {
            if (string.IsNullOrWhiteSpace(state))
            {
                throw new ArgumentNullException(nameof(state));
            }

            OpenIdConnectAuthorizationState authState;

            // Decrypt, decode and deserialize
            try
            {
                var cryptoProvider = new EncodingCryptoProvider();
                var decryptedState = cryptoProvider.DecodeAndDecrypt(state);

                authState = JSON.Deserialize <OpenIdConnectAuthorizationState>(decryptedState);
            }
            catch (Exception exception)
            {
                throw new AuthenticationException("The authorization state is invalid.", exception);
            }

            return(ValidateAuthState(authState));
        }
        /// <summary>
        ///     Gets the authorization code request URL for the specified identity provider.
        /// </summary>
        /// <param name="idpLoginRequest">The oidc provider.</param>
        /// <param name="requestBaseUrl">The base url message.</param>
        /// <returns>Task&lt;Uri&gt;.</returns>
        /// <exception cref="System.ArgumentNullException">
        /// </exception>
        public async Task <Uri> GetAuthorizationCodeRequestUrl(IdentityProviderLoginRequest idpLoginRequest, Uri requestBaseUrl)
        {
            if (idpLoginRequest == null)
            {
                throw new ArgumentNullException(nameof(idpLoginRequest));
            }

            if (requestBaseUrl == null)
            {
                throw new ArgumentNullException(nameof(requestBaseUrl));
            }

            if (string.IsNullOrWhiteSpace(idpLoginRequest.Tenant))
            {
                throw new ArgumentException(@"The tenant is invalid.", nameof(idpLoginRequest));
            }

            if (idpLoginRequest.IdentityProviderId <= 0)
            {
                throw new ArgumentException(@"The identity provider is invalid.", nameof(idpLoginRequest));
            }

            if (string.IsNullOrWhiteSpace(idpLoginRequest.RedirectUrl))
            {
                throw new ArgumentException(@"The redirect url is invalid.", nameof(idpLoginRequest));
            }

            long   tenantId;
            long   oidcProviderId;
            string oidcConfigurationUrl;
            string oidcClientId;
            bool   alwaysPrompt;

            using (new SecurityBypassContext())
                using (new TenantAdministratorContext(idpLoginRequest.Tenant))
                {
                    var oidcIdentityProvider = ReadiNow.Model.Entity.Get <OidcIdentityProvider>(idpLoginRequest.IdentityProviderId, GetOidcProviderFieldsToLoad());

                    if (oidcIdentityProvider == null)
                    {
                        throw new AuthenticationException("The identity provider does not exist.");
                    }

                    ValidateOidcProviderFields(oidcIdentityProvider);

                    // Store any required entity model fields upfront.
                    // Any code running after the await statement may run a different thread
                    tenantId             = RequestContext.TenantId;
                    oidcProviderId       = oidcIdentityProvider.Id;
                    oidcClientId         = oidcIdentityProvider.OidcClientId;
                    oidcConfigurationUrl = oidcIdentityProvider.OidcIdentityProviderConfigurationUrl;
                    alwaysPrompt         = oidcIdentityProvider.OidcAlwaysPrompt ?? true;
                }

            OpenIdConnectConfiguration oidcConfig;

            try
            {
                // Get the configuration
                oidcConfig = await _configurationManager.GetIdentityProviderConfigurationAsync(oidcConfigurationUrl);
            }
            catch (Exception ex)
            {
                throw new OidcProviderInvalidConfigurationException(ex);
            }

            var oidcProtocolValidator = new OpenIdConnectProtocolValidator();

            // Create authorization state
            var authStateObject = new OpenIdConnectAuthorizationState
            {
                Timestamp          = DateTime.UtcNow.Ticks,
                RedirectUrl        = idpLoginRequest.RedirectUrl,
                IdentityProviderId = oidcProviderId,
                TenantId           = tenantId,
                Nonce = oidcProtocolValidator.GenerateNonce()
            };

            // Serialize and encrypt state
            var stateJson      = JSON.Serialize(authStateObject);
            var cryptoProvider = new EncodingCryptoProvider();
            var encryptedState = cryptoProvider.EncryptAndEncode(stateJson);

            // Create code request oidc message
            var oidcMessage = new OpenIdConnectMessage
            {
                ClientId      = oidcClientId,
                IssuerAddress = oidcConfig.AuthorizationEndpoint,
                RedirectUri   = GetOidcAuthResponseUri(requestBaseUrl, idpLoginRequest.Tenant),
                Scope         = "openid email",
                ResponseType  = "code",
                State         = encryptedState,
                Nonce         = authStateObject.Nonce,
                Prompt        = alwaysPrompt ? "login" : null
            };

            // Get request url
            return(new Uri(oidcMessage.CreateAuthenticationRequestUrl()));
        }