validating password with uppercase and lowercase - c#

This is my password textbox aspx elements:
<label for="password">Password</label>
<asp:Text Box ID="User Password" runat ="server" Text Mode ="Password" ></asp:Text Box>
This is my code behind
protected void LoginSubmit_Click(object sender, EventArgs e)
{
BOL ObjectBOL = new BOL();
BAL ObjectBAL = new BAL();
ObjectBOL.UserName_value = UserText.Text;
ObjectBOL.UserPassword_value = UserPassword.Text;
try
{
String Login = ObjectBAL.LoginBAL(ObjectBOL);
int i = int.Parse(Login);
if (i > 0)
{
Response.Redirect("dashboard.aspx", false);
}
else
{
//UserText.Text = "";
//UserPassword.Text = "";
lblMsg.Text = (" Login Failed.... Try Again...");
}
}
catch (Exception LoginException)
{
throw LoginException;
}
finally
{
ObjectBAL = null;
}
}
When the user enters the password in upper case or lower case letters it was accepting the value and redirecting to the next page.
SqlCommand cmd = new SqlCommand ("select count (*) from UserTable where User_Name='" + Login.UserName_value +
"'and User_Password='" + Login.UserPassword_value + "'", con);
string str = cmd.ExecuteScalar().ToString();
return str;

There are two solution for this problem
Change your database table nature .By default SQL server do the case insensitive comparison you need to alter your db table.
ALTER TABLE UserTable
ALTER COLUMN User_Password VARCHAR(20)
COLLATE Latin1_General_CS_AS
Or you can append COLLATE Latin1_General_CS_AS to every query at last without altering your table.
Latin1_General_CS_AS is for case sensitive and Latin1_General_CI_AS for case insensitive comparison
how to make case sensitive comparison in SQL Server
Or you can convert your password in binary then store in db and compare binary content from db and user entered password.
Suggestion
You can go with first solution it will take less time. but second solution is more secure then first one. Do read about this on google. you will find the cons of the directly storing password in plain text.
As mentioned in comment your code is vulnerable to SQL Injection attack. Use parametrize query instead.

Update your SQL Command query with COLLATE Latin1_General_CS_AS as mentioned below to compare string with case sensitive:
SqlCommand cmd = new SqlCommand ("select count (*) from UserTable where User_Name='" + Login.UserName_value +
"' and User_Password='" + Login.UserPassword_value + "' COLLATE Latin1_General_CS_AS", con);
string str = cmd.ExecuteScalar().ToString();
return str;

So I see a couple issues here that you should really look at, let me address those then I'll help with the question you asked.
First, as mentioned in the comments by #Erik Philips, you should be using parameterized queries rather than string concatenation.
Second, you really should be hashing your passwords using a strong hashing algorithm, so if/when your DB gets compromised, you don't divulge all your user's passwords to the attacker.
Ok, as for the actual question at hand you have two options. The far more common solution I've seen is to do the Select just based on the user name, then compare the hashed passwords in C# code to determine whether the user should be logged in or not.
The other option would be to use a case sensitive query in SQL, which in SQL Server requires you to assign a collation via the COLLATE command (either to the query or to the column), perhaps assigning it to whichever relevant character set you want: http://msdn.microsoft.com/en-us/library/ms144250(v=sql.105).aspx

You need to change your sql query only. no need to change table nature and anything else.
SqlCommand cmd = new SqlCommand ("select count(*) from UserTable where User_Name COLLATE Latin1_general_CS_AS ='" + Login.UserName_value + "'and User_Password COLLATE Latin1_general_CS_AS ='" + Login.UserPassword_value + "'", con);
con.Open();
string str = cmd.ExecuteScalar().ToString();
con.Close();
return str;

SqlCommand cmd = new SqlCommand ("select COUNT(*) from UserTable where (CAST(User_Name as varbinary(50))=cast('"+ Login.UserName_value+"' as varbinary)) and (CAST(User_Password as varbinary(50))=cast('"+Login.UserPassword_value+"' as varbinary)),con);
con.Open();
string str = cmd.ExecuteScalar().ToString();
con.Close();
return str;
try this this will work

Please refer the below link, I think as mentioned above collate is the way to go about.
http://www.mytecbits.com/microsoft/sql-server/case-sensitive-search-fetching-lowercase-or-uppercase-string

Related

Strange thing is data inside SQL Server Management Studio

I am making a simple project in ASP.NET and have this code to proceed to login, detect the role and open the exact page.
string cmdText = "SELECT Username,Role FROM Login WHERE Username = '" + TextBox1.Text + "' AND Password = '" + TextBox2.Text + "'";
string username = "";
string role = "";
using (SqlCommand SelectCommand = new SqlCommand(cmdText, connectionstring))
{
SqlDataReader myReader;
connectionstring.Open();
myReader = SelectCommand.ExecuteReader();
while (myReader.Read())
{
username = myReader["Username"].ToString();
role = myReader["Role"].ToString();
}
myReader.Close();
Response.Redirect(role + ".aspx");
}
I set it role+".aspx" because I was having some weird error with the if function.. it wasn't working properly..
But still was having problem redirecting to the page.. and I notice this
So, confused by this error I decided to check the data in SQL Server, and there is this:
There are 5 white spaces after the role.. I tried to delete them. But after save the data the spaces apear again.. I notice that the same thing is with the name and password
but now there are 9 white spaces.. looks like SQL Server Management Studio is trying to fill the max 10 letters...
Username, password and role are nchar(10) type.. is that the problem?
Should I change to fix that? or it can be done on other way
An nchar column stores its values in a fixed length space. If you declare a column to be of type nchar(10) then your values are all padded with spaces to reach the 10 characters length.
If you can change your schema then change the column to be of nvarchar(10) type and (not sure about it) probably you need to reedit all the values already there.
See What is the difference between char, nchar, varchar, and nvarchar in SQL Server?
If you can't change the schema then you could Trim the results in code
Response.Redirect(role.Trim() + ".aspx");
However, looking at your code, I see a very big problem. You are using the famigerate string concatenation to build your query. This is a well know weakness on code and leads to Sql Injection attacks and to parsing errors.
You should fix ASAP that query using parameters
string cmdText = "SELECT Role FROM Login WHERE Username = #name AND Password = #pass";
// You already know the username
string username = textBox1.Text;
string role = "";
using (SqlCommand SelectCommand = new SqlCommand(cmdText, connectionstring))
{
connectionstring.Open();
SelectCommand.Parameters.Add("#name", SqlDbType.NVarChar).Value = textBox1.Text;
SelectCommand.Parameters.Add("#pass", SqlDbType.NVarChar).Value = textBox2.Text;
using(SqlDataReader myReader = SelectCommand.ExecuteReader())
{
while (myReader.Read())
{
role = myReader["Role"].ToString();
}
}
Response.Redirect(role.Trim() + ".aspx");
}
As a final note, consider that storing passwords in clear text in a database is another security weakness to avoid. A well know good practice is to hash and salt a password before storing it in the database
You should use nvarchar(10) instead of nchar(10). char and nchar will always have a fixed length. So if you store an 'a' in a nchar(10) or char(10) it will get padded to the right with spaces to 10 charachters. If you store it as a nvarchar(10) it will be stored as the length of your string.
Only use nchar and char when the length of the column will always be the same.
After converting from nchar to nvarchar. You should also update the data in your columns so they won't have the trailing spaces anymore. (Do this for all the columns which you wish to convert)
update Login set Role = LTRIM(RTRIM(Role))
You can use trim() in the c# code to prevent %20 (blank space) in the url, It is because the role returned by database is 'admin____' (____ = blank space) and not 'admin', There are two options,
1. string cmdText = "SELECT Username,LTrim(RTrim(Role)) FROM Login WHERE Username = '" + TextBox1.Text + "' AND Password = '" + TextBox2.Text + "'";
(or)
2. Response.Redirect(role.trim() + ".aspx");

please tell me why this query not working

I have in the DB Sid and password and it contain the Sid=senan and the password=pass1234
when I enter this details into my login screen always I get fail messagebox
SqlDataAdapter cmd = new SqlDataAdapter("select Count(*) from [user] where Sid=' " + textBox1.Text + " ' and password='" + textBox2.Text + "'", cnn);
DataTable dt = new DataTable();
cmd.Fill(dt);
if (dt.Rows[0][0].ToString() == "1")
MessageBox.Show("pass");
else
MessageBox.Show("fail");
The error arises from a simple typo. You have spaces added to the value passed for the Sid condition.
However your query should be rewritten in this way
string cmdText = "select Count(*) from [user] where Sid=#sid and password=#pwd";
SqlCommand cmd = new SqlCommand(cmdText, cnn)
cmd.Parameters.AddWithValue("#sid", textBox1.Text);
cmd.Parameters.AddWithValue("#pwd", textBox2.Text);
int count = Convert.ToInt32(cmd.ExecuteScalar());
if (count > 0)
MessageBox.Show("pass");
else
MessageBox.Show("fail");
This approach uses a parameterized query to avoid Sql Injection, and uses directly an SqlCommand without building the SqlDataAdapter and a DataTable. The SqlCommand.ExecuteScalar is the correct method to use when you need to retrieve simply the first column of a single row or call a scalar T-SQL function like COUNT()
As a side note, keep in mind that storing passwords in clear text in your database is a big security concern. Whoever has access to the database will be able to read the passwords of every user. The passwords should be stored as a computed hash and checked repeating the hashing algorithm on the user entered data.

How does JET OLEDB Parameters compare strings with text field in and Access DB

I have the following update query in C# using a JET OLEDB connection, connecting to a ms access DB file. The query fails to change the fields, it runs correctly but just 0 rows changed.
I think the problem is how parameters are processed and compared against the DB but have no idea how to fix it.
The "User" column is set as text. I have an insert statement that works perfectly set up in the same fashion with the parameters.
com.CommandText = "UPDATE [ExamMaster] SET [User] = (DLookup('LName', 'Users', 'ID' = '#correctUser') WHERE [User] = '#user'";
com.Parameters.AddWithValue("#correctUser", correctUser);
com.Parameters.AddWithValue("#user", userName);
If I do not use a parameter for the where clause and just insert it into the command string like so:
WHERE [User] = '"+userName+"'";</code>
it will update the DB just fine. What am I missing here?
UPDATE:
With or with single quotes makes no difference and rearranging the order of the parameters does not work either.
The order matters. I "think" in your query user is being called first before the correctUser due to the DLOOKUP function.
com.Parameters.AddWithValue("#user", userName);
com.Parameters.AddWithValue("#correctUser", correctUser);
You don't need to single quote parameters:
WHERE [User] = #user";
and I'll guess that the DLOOKUP doesn't need the single quotes either, just [brackets] if the field name has a space or is a reserved word (which [User] might be).
You will need to change that a bit, try:
OleDbConnection cn = new OleDbConnection(aconnectionstring);
cn.Open();
//testing
int correctUser = 1;
string userName = "1";
OleDbCommand com = new OleDbCommand();
com.Connection = cn;
//You cannot have a parameter in DLookUp
com.CommandText = "UPDATE [ExamMaster] SET [User] = " +
"DLookup('LName', 'Users', 'ID = " + correctUser + "') WHERE [User] = #user";
com.Parameters.AddWithValue("#user", userName);
//You must execute the query
com.ExecuteNonQuery();

Adding to/Accessing a database in ASP.Net in C#

I have been working on this school assignment and have gotten to a point at which I have been stuck for a few days now. My ASP.net web page is supposed to allow the user to create an account and login. However, no matter how many times I fill in the Create Account form, it doesn't seem to get added to the database.
Here is my User class, which holds the createAccount Method
public class Userr
{
//Constructor for the Account Creation method(createAccount)
public string createAccount(string strFname, string strLname, string strUname, string address, string city, string state, string phone, string zip, string email,string password)
{
string i="";
string storedProcText = ("INSERT INTO User Values('#ID," +strUname +"','"+strFname +"','"+ strLname +"','"+address +"','"+city +"','"+state+"','"+zip+"','"+phone+"','"+ email +"','"+ password );
ArrayList parms = null;
DataAccess dataAccess = new DataAccess();
int result = dataAccess.insertUpdateData(parms,storedProcText );
i =result.ToString();
return i;
}
public string Login(string strUsername, string strPassword)
{
DataAccess objDA = new DataAccess();
int result = objDA.LoginUser(strUsername, strPassword);
}
}
Here is my method for updating(stored in the dataAccess object/class
//Constructor for the update method
public int insertUpdateData(ArrayList items, String strProcedureName)
{
int i = 0;
string strConn = WebConfigurationManager.ConnectionStrings["TicketsConnectionString"].ConnectionString;
SqlConnection myConnection = new SqlConnection(strConn);
string sqlText = strProcedureName;
SqlCommand myCommand = new SqlCommand(sqlText);
myCommand.Connection = myConnection;
myCommand.CommandType = CommandType.StoredProcedure;
try
{
using (myConnection)
{
myConnection.Open();
i = myCommand.ExecuteNonQuery();
//grdData.DataSource = myReader;
// grdData.DataBind();
}
}
catch (Exception err)
{
}
return i;
}
The User table contains the follwing fields in order: ID, UserID, FirstName,LastName, Address, City, State, Zip,Phone,EmailAddress,Password
Is my SQL statement wrong, or what? I am at the end of my rope here.
So, off the bat, I see a few issues:
You set your myCommand.CommandType = CommandType.StoredProcedure but, the syntax you provided is not a stored proc. A stored proc would take a name value list of params, which is null in your case.
Lets say you didn't mean to use stored procs, in which case, your sql syntax is incorrect. You don't need the #ID parameter, unless you are passing it in (in which case, you didn't set it). It should be something like this (without knowing the structure of your table):
string storedProcText = ("INSERT INTO User Values("'" +strUname +"','"+strFname +"','"+ strLname +"','" + address +"','"+city +"','"+state+"','"+zip+"','"+phone+"','"+ email +"','"+ password + "'");
This is given that the values you are inserting matches your table exactly. If not, you will need to specify the table field names in your query as well, like so:
string storedProcText = ("INSERT INTO User(username, firstName, lastName, field4, field5, field6) Values("'" +strUname +"','"+strFname +"','"+ strLname +"','" + address +"','"+city +"','"+state+"','"+zip+"','"+phone+"','"+ email +"','"+ password + "'");
The way to do this using stored procs is this:
SqlParameter[] parameters = {
new SqlParameter("#param1", SqlDbType.NVarChar, 50),
new SqlParameter("#param2", SqlDbType.VarChar, 100),
new SqlParameter("#param3", SqlDbType.VarChar, 100),
new SqlParameter("#param4", SqlDbType.VarChar, 100),
new SqlParameter("#param5", SqlDbType.VarChar, 100),
new SqlParameter("#param6", SqlDbType.VarChar, 100)
};
parameters[0].Value = strFname;
parameters[1].Value = strLname;
.........
.........
[all the parameters you need]
You need to create a stored proc, also (obviously)
And then you call your dataaccess layer just like you are doing.
Steps for making this work:
1) Don't catch and swallow every exception. The exception will tell you what you are doing wrong here.
2) As Caspar Kleijne points out, you need to put the password in quotes.
3) As I point out, you need to add a parenthesis.
4) You should also use parameterized SQL queries
5) You probably shouldn't be passing the ID,
Here's the corrected SQL string for #2 and #3:
string storedProcText = ("INSERT INTO User Values('#ID,"
+strUname +"','"+strFname +"','"
+ strLname +"','"+address +"','"
+city +"','"+state+"','"
+zip+"','"+phone+"','"
+ email +"','"+ password
+"')" );
It'll take some refactoring to use parameterized queries, and this is a homework project, so I'll leave that as an exercise for you.
So, to start from the beginning, have you stepped through this code with the debugger and determined if it's throwing an exception or returning zero rows modified?
The most worrisome thing is the insertion of the #ID column. If this is an Identity column you shouldn't be inserting this value. If it's not, I don't see you assigning a value to it anywhere.
EDIT:
So as has been mentioned by others here you have some structural issues in you query.
I took your code and threw it in a quick project and here's what your statement looks like.
INSERT INTO User Values('#ID,UserName','FirstName','LastName','123 Some Street','SomeTown','State','54555','555-444-3333','email#email.com','ITS_A_SECRET!
Notice the end of the query. The password field isn't escaped with a closing ' and the param list is not closed with a closing bracket.
A second problem is that #Id field. Is your column in the database an identity field? (It should be) If so, just remove that.
Now, here's the real kicker. Is your table name User? That's a reserved word in SQL server so you'll get errors in your query as is. Format you query like the following and it will work.
string storedProcText = ("INSERT INTO [dbo].[User] Values('" + strUname + "','" + strFname + "','" + strLname + "','" + address + "','" + city + "','" + state + "','" + zip + "','" + phone + "','" + email + "','" + password + "')");
The other issue, as mentioned is that you have the command type set to Stored Procedure when you are not using one.
Modifying you command type to text:
myCommand.CommandType = CommandType.Text;
After I made these modifications and ran your code I ended up with a record in the database.
The most important thing to check right now is that ID field. Is it an identity column? Make sure it is and then remove it from your statement.
In the insert you are trying to insert #ID which first of all most likely would be an identity column, and unless you set IDENTITY_INSERT ON on that table, will throw an exception, second, even if it was not an identity column, you are not providing the parameter definition for the #ID parameter to the command.
Try removing #ID from the insert statement, and pass in everything else, but ID.
As a side note, your SQL Statement is prone to SQL Injection attacks since you're concatenating sql command string and values provided by user into one string. I would recommend using parameters instead the actual values and then adding parameters to the sql command later.
I cannot post everything as a comment , but can you do one thing..
put a break point and take the contents of this string
string storedProcText = ("INSERT INTO User Values('#ID," +strUname +"','"+strFname +"','"+ strLname +"','"+address +"','"+city +"','"+state+"','"+zip+"','"+phone+"','"+ email +"','"+ password );
and paste the value of storeProcText directly in the database and see if it can successfuly run and create a record for you.
break and debug should fix your problem
Please Comment out this statement:
myCommand.CommandType = CommandType.StoredProcedure’;
You can use a sql script directly.

Exception while inserting values in to SQL table through C#

HI i had manullay created textbox's and then used it for creating a new user. I am using SQL SERVER 2005 for backend and Visual Server 2008 for front..
I have this LoginAccount table which stores details of the new user created. When i Click the button(in which i have written code to create a new user through SQL insert),
string strConnection = ConfigurationManager.ConnectionStrings"FHDLConnectionString"].ToString();
SqlConnection sqlConnection = new SqlConnection(strConnection);
string username = TextBox1.Text;
string password = TextBox2.Text;
string confirmpass = TextBox3.Text;
string SQLQuery = "Select username From LoginAccount where '" + username + "'";
string SQLQuery1 = "Insert into LoginAccount values ('" + username + "','" + password + "')";
SqlCommand command = new SqlCommand(SQLQuery, sqlConnection);
SqlCommand command1 = new SqlCommand(SQLQuery1, sqlConnection);
sqlConnection.Open();
string CheckUsername = "";
if (password.ToString() != confirmpass.ToString())
{
Literal1.Text = " Password's does not match ";
}
else
{
try
{
CheckUsername = command.ExecuteScalar().ToString();
}
catch (Exception er)
{
Literal1.Text = " Username already exists ";
}
string insertQuery = "";
try
{
insertQuery = command1.ExecuteScalar().ToString();
Server.Transfer("Login_Created.aspx");
}
catch (Exception er)
{
Literal1.Text = " Could not create the user, Please retry with some other option ";
}
}
sqlConnection.Close();
I am getting these exception's
An expression of non-boolean type specified in a context where a condition is expected, near 'fhdl'
This error i got at the first catch
and
Object reference not set to an instance of an object.
This for at the last catch.
But the main thing is i am able to insert the username and password into the LoginAccount table!!!!!!! i.e. when i saw the table contents i could see the new user created in that table.
The other thing is This code executed perfectly once before but not now :(
Please could anyone tell me where am i going wrong?
I am new to C# with SQl ...
1 - ExecuteScalar() means that there's a return value. The insert doesn't have a return value. Use ExecuteNonQuery instead.
2 - Also, for the insert statement, specify the fields you're inserting into. Without specifying the fields, it's trying to insert into the first two columns of the table, which may not be username and password.
insert into LoginAccount(UserName, Password) values ....
3 - your select statement is incorrect.
select from LoginAccount where UserName='... You're missing the field name.
Three things:
Your first query doesn't do what you want it to. It resolves to:
Select username From LoginAccount where 'username'
You want to check the username against the database.
This code leaves you wide open to SQL Injection attacks. See this article for how to prevent them in C#.
On a similar note, you really don't want to store passwords in the clear in your database either.

Categories

Resources