I have a simple C# windows form which acts as a login, but also has a form to change the password of a user.
When you click on Change Password the form loads with a text box of current password, new pass and confirm new pass, and one save button.
I have stored username in label so that current password can be checked if it is valid from database or not.
I am storing these in a table which I created in Microsoft SQL Server 2008.
The code is as follows so far.
SqlConnection connect = new SqlConnection(str);
connect.Open();
string username = label_username.Text;
string password = textBox_Current.Text;
string newPassword = textBox_New.Text;
string confirmPassword = textBox_Verify.Text;
string sqlquery = "UPDATE [Member] SET Password=#newpass where Username=#username";
SqlCommand cmd = new SqlCommand(sqlquery, connect);
cmd.Parameters.AddWithValue("#newpass", textBox_Verify.Text);
cmd.Parameters.AddWithValue("#username", label_username.Text);
cmd.Parameters.AddWithValue("#password", textBox_Current.Text);
cmd.Connection = connect;
cmd.ExecuteNonQuery();
sqlDataReader reader = null;
reader = cmd.ExecuteReader();
while (reader.Read())
{
if ((textBox_New.Text == reader["newPassword"].ToString()) & (textBox_Verify.Text == (reader["confirmPassword"].ToString()))) { }
}
MessageBox.Show("Password Changed Successfully!");
this.Close();
While executing above code, password change but I want to:
check validation like if the user had typed wrong password in current password.
newpassword and confirm password .
when user click on first save bottom blank password should not store in database, rather should give message 'please type the password'
How can this be done?
You really should not be storing these passwords in plain text. You should hash the password and store the hash. Then if you want to check if a password is correct hash the password the user typed and compare it to the hash stored for the user.
But, it sounds like you need help getting a value out of the database for the current user. Putting something like this in there, ought to do this for you. Please note that like I said above, this should really be retrieving a hash of the password, not the actual password in plain text.
string sqlquery = "SELECT Password FROM [Member] where Username=#username";
SqlCommand cmd = new SqlCommand(sqlquery, connect);
cmd.Parameters.AddWithValue("#username", label_username.Text);
cmd.Connection = connect;
string currentPassword = (string)cmd.ExecuteScalar();
if (currentPassword == textBox_Current.Text)
{
// PASSWORD IS CORRECT, CHANGE IT, NOW.
} else {
// WOW EASY BUDDY, NOT SO FAST
}
First you should use password hashing in your application, thus the password fields of the database should hold the hashed values.
Assuming this, to accomplish your goals,
consider your string username -> Hash it -> write a query to check whether that hashed value and the user's password's hash value stored in the database is the same
consider string password and string newPassword in your code -> Hash both -> check whether the hash values are the same
consider string password and string newPassword -> check whether each is null or the length is 0
Also you should perform these tasks in the following order:
1 -> 3 -> 2
Hope this helps...
protected void btn_PasswordChange(object sender, EventArgs e)
{
string constring = DataAccess.GetConnection();
SqlConnection con = new `SqlConnection`(constring);
{
if (con.State != ConnectionState.Open)
con.Open();
}
string str = "select * from tbl_MemberLogin where Password='" + txtoldpwd.Text + "'";
DataTable DT = new DataTable();
DT = objdut.GetDataTable(str);
if (DT.Rows.Count == 0)
{
lblmsg.Text = "Invalid current password";
lblmsg.ForeColor = System.Drawing.Color.Red;
}
else
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "update tbl_MemberLogin set Password='" + txtnewpwd.Text + "' where UserName='" + Session["UserName"].ToString() + "'";
cmd.ExecuteNonQuery();
lblmsg.Text = "Password changed successfully";
lblmsg.ForeColor = System.Drawing.Color.Green;
}
}
Related
What should i do to make this case sensitive?
When I try this code with input in different cases but with the same spelling of username and password, it still logs in. My fields are all varchar in database.
if (user_txt.Text != "" & pass_txt.Text != "")
{
string queryText = "SELECT Count(*) FROM stiguidancesample.users " + "WHERE username = #Username AND password = #Password";
MySqlConnection cn = new MySqlConnection(MyConnectionString);
MySqlCommand cmd = new MySqlCommand(queryText, cn);
{
cn.Open();
cmd.Parameters.AddWithValue("#Username", user_txt.Text); // cmd is SqlCommand
cmd.Parameters.AddWithValue("#Password", pass_txt.Text);
int result = Convert.ToInt32(cmd.ExecuteScalar());
if (result > 0)
MessageBox.Show("Loggen In!");
else
MessageBox.Show("User Not Found!");
}
}
I don't know if all databases are the same but SQL Server and MySQL are both apparently case-insensitive when comparing for text equality. That's as it should be for a login. It shouldn't matter what case the user enters their user name in; it should still match.
As for the password, you should not be saving it directly so it shouldn't matter. You should be hashing the password and storing that. The chances of anyone entering a password value that leads to text containing the same characters in a different case as the hash that you have stored in the database is next to nothing.
To expand on that, you hash the password and save the result when the user registers and then, when they login, you hash the password they provide and compare that to the value in the database. If the hash values match then the passwords are considered to match.
The collation is relevant in how the strings are compared.
See for e.g. this answer here:
How can I make SQL case sensitive string comparison on MySQL?
or read the manual here: http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html
Your code should be like below
if (user_txt.Text != "" & pass_txt.Text != "")
{
string queryText = "SELECT Count(*) FROM stiguidancesample.users " + "WHERE username = #Username AND password = #Password COLLATE SQL_Latin1_General_CP1_CS_AS ";
MySqlConnection cn = new MySqlConnection(MyConnectionString);
MySqlCommand cmd = new MySqlCommand(queryText, cn);
{
cn.Open();
cmd.Parameters.AddWithValue("#Username", user_txt.Text); // cmd is SqlCommand
cmd.Parameters.AddWithValue("#Password", pass_txt.Text);
int result = Convert.ToInt32(cmd.ExecuteScalar());
if (result > 0)
MessageBox.Show("Loggen In!");
else
MessageBox.Show("User Not Found!");
}
}
Just add
COLLATE SQL_Latin1_General_CP1_CS_AS
after your #Password in query text.
Below is the code that is executed when the user clicks the submit button. However, everytime I try it I get an error which reads "Syntax error in FROM clause"
What I'm trying to do is check the values entered in te login screen against the values stored in the database, but there seems to be an issue with my FROM clause that I am not picking up on. Any pointers are appreciated.
string userName = "";
string passWord = "";
userName = txtUserName.Text;
passWord = txtPassword.Text;
string conString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\kazan_000\Desktop\Risk Manager\Risk Manager\Risk Manager Database 2.0.accdb";
string cmdText = "SELECT * from User where userName=? and passWord=?";
using (OleDbConnection con = new OleDbConnection(conString))
using (OleDbCommand cmd = new OleDbCommand(cmdText, con))
{
con.Open();
cmd.Parameters.AddWithValue("#p1", userName);
cmd.Parameters.AddWithValue("#p2", passWord);
int result = (int)cmd.ExecuteScalar();
if (result > 0)
MessageBox.Show("Login Successful");
else
MessageBox.Show("Invalid Credentials, Please Re-Enter");
}
Problem : user and password are reserved words in MS-Access .
Solution : you need to enclose the reserved words in square brackets []
Try This:
string cmdText = "SELECT * from [User] where userName=? and [passWord]=?";
Strange mixture you have there.
"Select * From [User] Where userName = #p1 and [password] = #p2" is what you are looking for.
This question already has answers here:
Simple SELECT statement fails with "syntax to use near", "ORA-00906", "syntax error at or near" or "syntax near the keyword"
(2 answers)
Creating table names that are reserved words/keywords in MS SQL Server [closed]
(11 answers)
Closed 8 years ago.
I am having some problem when trying to check login credential for 3-tier project in C#.
Currently, I have a table named User with userName and password columns.
In my BusinessLogicLayer, I get the user input and pass them to dataAccessLayer:
public string checkCredential(string userName, string password)
{
string returnMessage = "";
User user = new User(userName, password);
Boolean success = user.checkCredential();
if (!success)
{
returnMessage += "Username and password does not match!";
}
else
{
returnMessage = "";
}
return returnMessage;
}
In my Data Access Layer, I got a method to check for login creddential:
public Boolean checkCredential()
{
Boolean result = false;
using (var connection = new SqlConnection(FFTHDb.connectionString)) // get your connection string from the other class here
{
SqlCommand command = new SqlCommand("SELECT userName, password FROM User WHERE userName = '" + userName + "' AND password = '" + password + "'", connection);
connection.Open();
using (var dr = command.ExecuteReader())
{
if (dr.Read())
{
result = true;
}
}
}
return result;
}
And I got a separated class to set the connection string:
public static string connectionString = DataAccessLayer.Properties.Settings.Default.DBConnStr;
public static SqlDataReader executeReader(string query)
{
SqlDataReader result = null;
System.Diagnostics.Debug.WriteLine("FFTHDb executeReader: " + query);
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(query, connection);
connection.Open();
result = command.ExecuteReader();
connection.Close();
return result;
}
There is no compilation errors. And I double checked for the table name and columns in database. However, it just keeps telling me that there is syntax error near User. I wonder why is it so.
Thanks in advance.
User is a reserved keyword on T-SQL. You should use it with square brackets like [User]
Also using parameterized queries always a good practice.
And Never store passwords in plain text! Use SHA-512 hash.
User is a reserved keyword so you need to add square brackets around it. For a list see here.
So, you should do it like this
SELECT userName, password FROM [User] WHERE userName =
Problem : the table name which you have provided is User is a Keyword in Transact-SQL.
Reserved Words
Solution: Enclose the reserved word User in square brackets [].
Solution 1:
SqlCommand command = new SqlCommand("SELECT userName, password FROM [User] WHERE userName = '" + userName + "' AND password = '" + password + "'", connection);
Solution 2:
SqlCommand command = new SqlCommand("SELECT userName, password FROM [User] WHERE userName= #username AND password = #password", connection);
command.Parameters.AddWithValue("#username",userName);
command.Parameters.AddWithValue("#password",password);
i am creating password change form. when i execute the form and fill the textboxes it give an exception with the message There is already and open DataReader associated with this command which must be closed first.
he is the code which i am using:
private bool CompareStrings(string string1, string string2)
{
return String.Compare(string1, string2, true, System.Globalization.CultureInfo.InvariantCulture) == 0 ? true : false;
}
private void button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection con1 = new SqlConnection();
con1.ConnectionString = "data source=.;Initial catalog=inventory;Integrated Security=true";
con1.Open();
SqlCommand cmd = new SqlCommand("SELECT ISNULL(username, '') AS username, ISNULL(password,'') AS password FROM login WHERE username='" + textBox1.Text + "' and password='" + textBox2.Text + "'", con1);
SqlDataReader dr = cmd.ExecuteReader();
string userText = textBox1.Text;
string passText = textBox2.Text;
while (dr.Read())
{
if (this.CompareStrings(dr["username"].ToString(), userText) &&
this.CompareStrings(dr["password"].ToString(), passText))
{
SqlCommand cmd2 = new SqlCommand("UPDATE login SET password='" + textBox3.Text + "'where username='" + textBox1.Text + "'", con1);
cmd2.ExecuteNonQuery();
MessageBox.Show("Password Changed Successfully");
}
else
{
MessageBox.Show("Incorrect Old password");
}
}
dr.Close();
con1.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
You cannot execute a command while a SqlDataReader is open on the same connection. You can do either of the two following things to change your code:
Create a second connection and run the update query on that second connection.
Store the data from the reader, close the reader and later update all data. In your case, you could store all usernames to update and update them in one update query using Username in (<yourlisthere>)
When you open a DataReader the connection serves only the requests coming from the DataReader. The SqlCommand used to Update the login table cannot run.
Unless you add this to your connectionstring
MultipleActiveResultSets = True;
Here you can find the reference to MARS
And here the words from MSDN about the DataReader
While the SqlDataReader is being used, the associated SqlConnection is
busy serving the SqlDataReader, and no other operations can be
performed on the SqlConnection other than closing it. This is the case
until the Close method of the SqlDataReader is called. For example,
you cannot retrieve output parameters until after you call Close.
As a side note, but very important. Do not use string concatenation to build sql commands. Use always a parameterized query
string cmdText = "UPDATE login SET password=#pwd where username=#usr";
using(SqlCommand cmd2 = new SqlCommand(cmdText, con1))
{
cmd2.Parameters.AddWithValue("#pwd", textBox3.Text);
cmd2.Parameters.AddWithValue("#usr", textBox1.Text);
cmd2.ExecuteNonQuery();
}
A parameterized query will avoid Sql Injection problems and let you simplify your command text.
This is true also for the SELECT query at the beginning of your code. Do not trust the input coming from your user
Another problem that you should be aware of is the storing of clear text passwords in your database. This is considered a very bad practice from a security point of view. You should apply an hash function to you password and store the result. While checking for the correct password you repeat the hash function on the user input and check the result against the hashed password stored in database
I am trying to develop a simple user management system for the admin of the web application. I am using ASP.NET Wizard Control for this task.
I just put a TextBox for writing the username and when the admin clicks on the Next button, the system should check if the username existed in the database or not. If it is existed, the system should display his information in a placeholder for the admin.
I am struggling with this task. I did the following in the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
//Session["Username"] = Username.Text;
string connString = "Data Source=localhost\\sqlexpress;Initial Catalog=testdb;Integrated Security=True";
string cmdText = "SELECT * FROM employee WHERE Username = #Username";
//For checking the user
if (Request.QueryString["Username"] != null)
{
String strUserName = Request.QueryString["Username"];
////Check userName Here
//String strReturnStatus = "false";
if (CheckUsername(Request.QueryString["Username"]) == true)
{
//strReturnStatus = "true";
try
{
SqlConnection conn = new SqlConnection(connString);
conn.Open();
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand(cmdText, conn);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine(myReader["Name"].ToString());
Console.WriteLine(myReader["Job"].ToString());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
//Response.Clear();
//Response.Write(strReturnStatus);
//Response.End();
}
}
private bool CheckUsername(string username)
{
string connString = "Data Source=localhost\\sqlexpress;Initial Catalog=testdb;Integrated Security=True";
string cmdText = "SELECT * FROM employee WHERE Username = '" + username + "'";
using(SqlConnection conn = new SqlConnection(connString))
{
conn.Open(); // Open DB connection.
using (SqlCommand cmd = new SqlCommand(cmdText, conn))
{
int count = (int)cmd.ExecuteScalar();
// True (> 0) when the username exists, false (= 0) when the username does not exist.
return (count > 0);
}
}
}
I tried to test this by writing any username in the TextBox, but I did not get any result when I clicked on Next button of the wizard that should redirect me to the placeholder or any control that should display the user information. What I want now is just showing the information of the user if his username existed in the database. How to do that?
First of all you need to understand the concept of page load and postbacks. The code written inside Page_Load will execute every time the page is loaded either by entering the URL in browser or by becuase of button click event. You should place the code that you want to execute only once in
if(!isPostback)
{
//code to be need to be executed for the first time
//only goes within this block
}
Then as Asken suggested have a look at SQL injection too
Now regarding the problem, in your Page_Load event you have:
string cmdText = "SELECT * FROM employee WHERE Username = #Username";
You need to set the value of #Username parameter and this is how you can do this:
myCommand.Parameters.Add("#Username", SqlDbType.VarChar, 30); //assumption: UserName column is of varchar type length of 30
nonqueryCommand.Parameters["#Username"].Value = strUserName;