I am trying to do lock user account for Invalid login attempts in Asp.Net C# by using Visual Studio 2019. Database is using MySql Workbench 8.0 CE. But facing the error
C# code shown as below:
using System;
using System.Data;
using MySql.Data.MySqlClient;
namespace Canteen_UAT
{
public partial class LoginDetail : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click1(object sender, EventArgs e)
{
MySqlConnection scon = new MySqlConnection("server = XXX.XXX.XX.XXX; user id = root; password = XXXXX; persistsecurityinfo = True; database = posdbms_uat");
String myquery = "select count(*) from posdbms_uat.logindetail where username='" + TextBox1.Text + "'";
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = myquery;
cmd.Connection = scon;
MySqlDataAdapter da = new MySqlDataAdapter();
da.SelectCommand = cmd;
DataSet ds = new DataSet();
da.Fill(ds);
String uname;
String pass;
String status;
//String lockstatus;
int attemptcount = 0;
if (ds.Tables[0].Rows.Count > 0)
{
uname = ds.Tables[0].Rows[0]["username"].ToString();
pass = ds.Tables[0].Rows[0]["password"].ToString();
status = ds.Tables[0].Rows[0]["status"].ToString();
scon.Close();
if (status == "Open")
{
if (uname == TextBox1.Text && pass == TextBox2.Text)
{
Session["username"] = uname;
Response.Redirect("Order.aspx");
}
else
{
Label2.Text = "Invalid Username or Password - Relogin with Correct Username & Password. No of Attempts Remaining : " + (2 - attemptcount);
attemptcount = attemptcount + 1;
}
}
else if (status == "Locked")
{
Label2.Text = "Your Account Locked Already : Contact Administrator";
}
else
{
Label2.Text = "Invalid Username or Password - Relogin wit Correct Username and Password.";
}
if (attemptcount == 3)
{
Label2.Text = "Your Account Has Been Locked Due to Three Invalid Attempts - Contact Administrator.";
setlockstatus(TextBox1.Text);
attemptcount = 0;
}
}
}
private void setlockstatus(String username1)
{
String mycon = "server = xxx; user id = root; password = xxx; persistsecurityinfo = True; database = posdbms_uat";
String updatedata = "Update posdbms_uat.logindetail set status='Locked' where username='" + username1 + "' ";
MySqlConnection con = new MySqlConnection(mycon);
con.Open();
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = updatedata;
cmd.Connection = con;
cmd.ExecuteNonQuery();
}
}
}
Not sure what might be causing this.
What I have tried:
I created a table as posdbms_uat, datatable match the column name in the database table and with appropriate datatype. Not sure how this error pops up.
The query:
String myquery = "select count(*) from posdbms_uat.logindetail where username='" + TextBox1.Text + "'";
...only returns the number of rows matching the WHERE condition - not the actual data in the rows. It should be fixed by specifying the columns you want to get:
String myquery = "select username, password, status from posdbms_uat.logindetail where username='" + TextBox1.Text + "'";
Also, you should consider using parametrization to avoid SQL injection (see this SO question). Another thing is, please do not store the password in plain text.
Related
I want to retrieve date and time according to login user in my ASP.NET web application using C#. The code I'm using is just returning the 1st row details.
I want date and time of current login user and bind it to with a label.
I have a table called Userdatatext with 3 columns:
UserName, UserText, LastEditTime
Sorry for my bad English.
Thanks in advance :)
My C# code
protected void Page_Load(object sender,EventArgs e)
{
if (Session["userName"] != null && Session["userName"] != "")
{
LblUser.Text = "Welcome " + Session["userName"].ToString() + "";
}
else
{
Session.Abandon();
Response.Redirect("Login.aspx");
}
try
{
string Connectionstring = ConfigurationManager.ConnectionStrings["DbLogns"].ToString();
SqlConnection objConection = new SqlConnection(Connectionstring);
objConection.Open();
SqlCommand objCommand = new SqlCommand("select LastEditTime from Userdatatext where UserName='" + Session["userName"] + "'", objConection);
DataSet objDataset = new DataSet();
SqlDataAdapter objAdapter = new SqlDataAdapter(objCommand);
objAdapter.Fill(objDataset);
string lastdatetime = objDataset.Tables[0].Rows[0][0].ToString();
Lbllastedit.Text = "Last edit on :-" + lastdatetime;
Lbllastedit.Font.Size = 15;
objConection.Close();
}
catch(IndexOutOfRangeException n)
{
Lbllastedit.Text = "Last edit :- no data found !";
Lbllastedit.Font.Size = 13;
}
}
Try this code with a SqlDataReader:
try
{
string lastdatetime = null;
string Connectionstring = ConfigurationManager.ConnectionStrings["DbLogns"].ToString();
SqlConnection objConection = new SqlConnection(Connectionstring);
objConection.Open();
SqlCommand objCommand = new SqlCommand("select LastEditTime from Userdatatext where UserName='" + Session["userName"] + "'", objConection);
SqlDataReader dr = objCommand.ExecuteReader();
if (dr.Read())
{
lastdatetime = dr["LastEditTime"].ToString();
}
dr.Close();
Lbllastedit.Text = "Last edit on :-" + lastdatetime;
Lbllastedit.Font.Size = 15;
objConection.Close();
}
I am new to C#. I have Activation Data Type Bit in my database default value 0.
My question is how can I block user to login before activation email send
after registration is completed the activation is null in database but still user can login how can I fix this problem please help.
Here is my code:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Loginbtn_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegisterConnectionString"].ConnectionString);
conn.Open();
string checkuser = "select count(*) from UserData where UserName='" + UserName.Text + "'";
SqlCommand com = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
string checkPasswordQuery = "select password from UserData where UserName='" + UserName.Text + "'";
SqlCommand passComm = new SqlCommand(checkPasswordQuery, conn);
string password = passComm.ExecuteScalar().ToString().Replace(" ", "");
if (password == Password.Text && UserName.Text == "Admin" )
{
Session["New"] = UserName.Text;
Response.Redirect("~/Admin/UserManager.aspx");
}
if (password == Password.Text)
{
Session["New"] = UserName.Text;
Response.Redirect("~/Account/UserPage.aspx");
}
else
{
invalidlbl.Text = "Please check your username and password";
}
}
}
Here is the image of my database:
You said activation is null in database. So, when user tried to login, fetch and check if the activation is still null in database and if so then just so a message to user saying activate your account first and redirect him/her to home page.
EDIT: per your comment, not going to give you full code but here is an example of what I am saying. BTW, consider using SQL Parameter to avoid SQL Injection attack.
string checkuser = "select count(*) from UserData where UserName=#uname and activation != null";
SqlCommand com = new SqlCommand(checkuser, conn);
com.Parameters.Add("#uname", SqlDbType.VarChar).Value = UserName.Text.Trim();
int temp = Convert.ToInt32(com.ExecuteScalar());
if(temp > 0)
{
// do processing
}
else
{
// not activated ... throw alert
}
I am new to c# and visual studios and i am creating a windows form application that requires a username and password to log in. I have successfully implemented the database to register a user but cannot seem to get the login to work. There is two errors in the code below:
private void btnLogin_Click(object sender, EventArgs e)
{
MySqlConnection con = new MySqlConnection();
con.ConnectionString = "datasource=127.0.0.1;port=3306;username=root;password=;";
Int32 verify;
string query1 = "Select count(*) from Login where Username='" + Username.Text + "' and Password='" + Password.Text + "' ";
MySqlCommand cmd1 = new MySqlCommand(query1, con);
con.Open();
verify = Convert.ToInt32(cmd1.ExecuteScalar());
con.Close();
if (verify > 0)
{
new FormMainMenu().Show();
this.Hide();
}
else
{
MessageBox.Show("Username or Password is Incorrect")
}
}
The Username.Text and the Password.Text are both underlined and says the name
does not exist in the current context.
If anyone has any solutions to this, I would be very grateful. Thanks
you can try this, you just to change the connection to MYSQL Connector.
public int GetScalarValue()
{
int result = 0;
using (SqlConnection cn = new SqlConnection("CONECTION_STRING"))
{
cn.Open();
using (SqlCommand cmd = new SqlCommand("select count(*) from login where username=#login and password=#password")) {
cmd.Parameters.Add("#login", SqlDbType.VarChar).Value = Username.Text;
cmd.Parameters.Add("#password", SqlDbType.VarChar).Value = Password.Text;
result = int.Parse(cmd.ExecuteScalar().ToString());
}
}
return result;
}
Here is a basic and simple approach to validate password, easy to understand if you are beginner level programmer. It checks for min length, digit, lower case, upper case, special characters in input password string.
private bool ValidPass(string pass)
{
bool passLength = false, hasDigit = false, hasUpper = false, hasLower = false, hasSpecialChar = false;
if (pass.Length >= 6)
passLength = true;
foreach (char c in pass)
{
if (char.IsDigit(c))
hasDigit = true;
else if (char.IsUpper(c))
hasUpper = true;
else if (char.IsLower(c))
hasLower = true;
}
string specialChar = "\\/~!##$%^&*()-_+={[]};:'\"|,<.>?";
foreach (char c in specialChar)
{
if (pass.Contains(c))
hasSpecialChar = true;
}
if (passLength && hasDigit && hasUpper && hasLower && hasSpecialChar)
return true;
return false;
}
I have hased my password right there on in the registration.aspx. having this code in my business layer:
public static string CreateSHAHash(string Phrase)
{
SHA512Managed HashTool = new SHA512Managed();
Byte[] PhraseAsByte = System.Text.Encoding.UTF8.GetBytes(string.Concat(Phrase));
Byte[] EncryptedBytes = HashTool.ComputeHash(PhraseAsByte);
HashTool.Clear();
return Convert.ToBase64String(EncryptedBytes);
}
and this code in the register page:
scm.Parameters.AddWithValue("#Password", BusinessLayer.ShoppingCart.CreateSHAHash(txtPW.Text));
Having the codes above, the password are being hashed in the DB and it is working fine when I log in with this code:
protected void btn_Login_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
string checkuser = "select count(*) from UserData where Username = '" + txtUser.Text + "'";
SqlCommand scm = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(scm.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
string checkPassword = "select Password from UserData where Username ='" + txtUser.Text + "'";
SqlCommand passCom = new SqlCommand(checkPassword, conn);
string password = passCom.ExecuteScalar().ToString();
if (password == BusinessLayer.ShoppingCart.CreateSHAHash(txtPassword.Text))
{
Session["New"] = txtUser.Text;
Response.Write("<script>alert('Logged In')</script>");
Response.Redirect("OrderNow.aspx");
}
else
{
lblcrederror.Text = ("Credentials dont match");
}
}
else
{
lblcrederror.Text = ("Credentials dont match");
}
However when I change it having this code in my changepassword.aspx, its not letting me in with my new password.
protected void btn_update_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(conn);
con.Open();
str = "select * from UserData ";
com = new SqlCommand(str, con);
SqlDataReader reader = com.ExecuteReader();
while (reader.Read())
{
if (BusinessLayer.ShoppingCart.CreateSHAHash(txt_cpassword.Text) == reader["Password"].ToString())
{
up = 1;
}
}
reader.Close();
con.Close();
if (up == 1)
{
con.Open();
str = "update UserData set Password=#Password where UserName='" + Session["New"].ToString() + "'";
com = new SqlCommand(str, con);
com.Parameters.Add(new SqlParameter("#Password", SqlDbType.VarChar, 50));
com.Parameters["#Password"].Value = BusinessLayer.ShoppingCart.CreateSHAHash(txt_npassword.Text);
com.ExecuteNonQuery();
con.Close();
lbl_msg.Text = "Password changed Successfully";
}
else
{
lbl_msg.Text = "Please enter correct Current password";
}
}
What am I missing here?
Check if the 50 truncates the hash.
com.Parameters.Add(new SqlParameter("#Password", SqlDbType.VarChar, 50));
On a sidenote i see that your solution is very open to SQL injection.
"select Password from UserData where Username ='" + txtUser.Text + "'";
A user can write sql statements in the textbox, and hijack your database, create his own tables or drop the whole database. You should always parameterize the queries. I see that you did that to the Update statement, but you should consider doing it for all of your variables.
This quickly creates a lot of code, so i would also consider making an SQL wrapper, that wraps in all of the things you repeat. When you are done refactoring it could look something like this:
var sql = new SqlWrapper("select Password from UserData where Username = #username", txtUser.Text);
var dataSet = sql.Execute();
Then you can hide all of your connectionstring, commands++ behind this wrapper and only tell the wrapper what you actually care about.
You should also consider using a salt for your password. If you and I have the same password, the hash will be the same. A salt will fix this problem.
A good article about password security -> https://crackstation.net/hashing-security.htm
I have written the code below for a login page, but doesn't seem to work.
The variable temp takes a value of 0.
protected void ButtonSbmt_Click(object sender, EventArgs e) {
//if (IsPostBack) {
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegConnectionString"].ConnectionString);
conn.Open();
string cmdstr = "select count(*) from Registration where username='" + TextBoxUsername.Text + "'";
SqlCommand checkuser = new SqlCommand(cmdstr, conn);
int temp = Convert.ToInt32(checkuser.ExecuteScalar().ToString());
if (temp == 1) {
string str = "select password from Registration where username='" + TextBoxUsername.Text + "'";
SqlCommand pass = new SqlCommand(str, conn);
string pass1 = pass.ExecuteScalar().ToString();
conn.Close();
if (pass1 == TextBoxPassword.Text) {
Session["new"] = TextBoxUsername.Text;
Response.Redirect("secure.aspx");
} else {
Label1.Visible = true;
Label1.Text = "invalid password";
}
}
}
Use the ASP.NET membership provider, and the ASP.NET login controls along with ASP.NET forms authentication. This is built-in functionality that ASP.NET provides; it works, it's secure, and you don't have to write the SQL statements and logic.
Lesson one on security - if there is built-in functionality, use it. It will always be better than starting to write your own.