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"); }
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) ); }
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.")); }
/// <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<Uri>.</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())); }