コード例 #1
0
ファイル: User.cs プロジェクト: avs009/gsf
			/// <summary>
			/// Changes the user's current password under AD authentication mode if the user is external, or creates
			/// a new pin (if account is in "new pin" mode) under RSA authentication mode.
			/// </summary>
			/// <param name="oldPassword">
			/// Current password under AD authentication. Current token under RSA authntication.</param>
			/// <param name="newPassword">
			/// New password under AD authentication; new pin under RSA authentication.
			/// </param>
			/// <returns>
			/// True if password was changed successfully under AD authentication mode, or new pin was created
			/// successfully under RSA authentication mode; otherwise False.
			/// </returns>
			public bool ChangePassword(string oldPassword, string newPassword)
			{
				
				// Don't proceed to change password or create pin if user account is not defined or is locked.
				if (! m_isDefined || m_isLockedOut)
				{
					return false;
				}
				
				switch (m_authenticationMode)
				{
					case AuthenticationMode.AD:
						// Under AD authentication mode, we allow the password to be changed only if the user is
						// an external user and after the user's current password has been verified.
						if (m_isExternal && Authenticate(oldPassword))
						{
							using (SqlConnection dbConnection = GetDatabaseConnection())
							{
								TVA.Data.Common.ExecuteScalar("dbo.ChangePassword", dbConnection, m_username, m_password, EncryptPassword(newPassword));
							}
							
							
							return true;
						}
						break;
					case AuthenticationMode.RSA:
						// Under RSA authentication mode, in order to create a pin, the account must actually be in
						// the "new pin" mode. If it is not, then repeated attempts to create a pin may result in the
						// account being placed in "next token" mode (i.e. equivalent to account being disabled). And
						// the problem is that we cannot verify if a account is actually in the "new pin" mode, because
						// a token can be used only once and no more than once.
						TVA.Security.Radius.RadiusClient client = null;
						try
						{
							// First, we try creating a pin against the primary RSA server.
							client = new TVA.Security.Radius.RadiusClient(RsaServer1, TVA.Security.Cryptography.Common.Decrypt(RadiusSharedSecret));
							
							return client.CreateNewPin(m_username, oldPassword, newPassword);
						}
						catch (ArgumentNullException)
						{
							// When we encounter this exception, the primary RSA server didn't respond.
							try
							{
								// Next, we try creating a pin against the backup RSA server.
								client.Dispose();
								client = new TVA.Security.Radius.RadiusClient(RsaServer2, TVA.Security.Cryptography.Common.Decrypt(RadiusSharedSecret));
								
								return client.CreateNewPin(m_username, oldPassword, newPassword);
							}
							catch (Exception)
							{
								// Absorb any other exception.
							}
						}
						catch (Exception)
						{
							// Absorb any other exception.
						}
						finally
						{
							if (client != null)
							{
								client.Dispose();
							}
						}
						break;
				}
				
			}
コード例 #2
0
ファイル: User.cs プロジェクト: avs009/gsf
			/// <summary>
			/// Authenticates user's credentials.
			/// </summary>
			/// <param name="password">Password to be authenticated.</param>
			/// <returns>True if authentication was successful; otherwise False.</returns>
			public bool Authenticate(string password)
			{
				
				// We will not authenticate if user account doesn't exist or is locked.
				if (! m_isDefined || m_isLockedOut)
				{
					return false;
				}
				
				// Authenticate based on the specified authentication mode.
				switch (m_authenticationMode)
				{
					case AuthenticationMode.AD:
						if (m_isExternal)
						{
							// User is external according to the security database.
							if (! string.IsNullOrEmpty(password))
							{
								// We'll validate the password against the security database.
								m_isAuthenticated = EncryptPassword(password) == m_password;
							}
						}
						else
						{
							// User is internal according to the security database.
							if (! string.IsNullOrEmpty(password))
							{
								// We'll validate the password against the Active Directory.
                                m_isAuthenticated = new UserInfo("TVA", m_username, true).Authenticate(password);
							}
							else
							{
								// The user to be authenticated is defined as an internal user in the security database,
								// but we don't have a password to authenticate against the Active Directory. ' In this
								// case the authentication requirement becomes that the user we're authenticating must
								// be user executing the request (i.e. accessing secure the app).
								string loginID = System.Threading.Thread.CurrentPrincipal.Identity.Name;
								if (! string.IsNullOrEmpty(loginID))
								{
									m_isAuthenticated = string.Compare(m_username, loginID.Split('\\')[1], true) == 0;
								}
							}
						}
						break;
					case AuthenticationMode.RSA:
						TVA.Security.Radius.RadiusClient client = null;
						RadiusPacket response = null;
						try
						{
							// We first try to authenticate against the primary RSA server.
							client = new TVA.Security.Radius.RadiusClient(RsaServer1, TVA.Security.Cryptography.Common.Decrypt(RadiusSharedSecret));
							response = client.Authenticate(m_username, password);
							
							if (response == null)
							{
								// We didn't get a response back from the primary RSA server. This is most likely
								// to happen when the primary server is unavailable, so we attempt to authenticate
								// against the backup RSA server.
								client.Dispose();
								client = new TVA.Security.Radius.RadiusClient(RsaServer2, TVA.Security.Cryptography.Common.Decrypt(RadiusSharedSecret));
								response = client.Authenticate(m_username, password);
							}
							
							if (response != null)
							{
								// We received a response back from the RSA server.
								switch (response.Type)
								{
									case PacketType.AccessAccept:
										// Credentials were accepted by the RSA server.
										m_isAuthenticated = true;
										break;
									case PacketType.AccessChallenge:
										// RSA server challenged our authentication request.
										if (client.IsUserInNewPinMode(response))
										{
											// If the user's account is in the "new pin" mode, we treat it as if it's
											// time for the user to change the password so appropriate input form is
											// served to the user.
											m_passwordChangeDateTime = DateTime.Now;
										}
										else if (client.IsUserInNextTokenMode(response))
										{
											// If the user's account is in the "next token" mode, we treat the account
											// as if it is disabled so the user must either email or call-in to get the
											// account enabled.
											m_isLockedOut = true;
										}
										break;
								}
							}
						}
						catch (Exception)
						{
							throw;
						}
						finally
						{
							if (client != null)
							{
								client.Dispose();
							}
						}
						break;
				}
				
				// Log successful or unsuccessful authentication result to the security database so that a user account
				// gets locked-out automatically after a set number of unsuccessful login attempts.
				using (SqlConnection dbConnection = GetDatabaseConnection())
				{
					TVA.Data.Common.ExecuteNonQuery("dbo.LogLogin", dbConnection, m_username, ! m_isAuthenticated);
				}
				
				
				return m_isAuthenticated;
				
			}