Login Comparing hash value in a database - sql

I am attempting to make a simple sign on portion of an app I am creating. To confirm sign in, I am just attempting to make sure that the hash value of the password entered, matches that which is stored in my local database: App_Users ) '
ButtonClick:
string AppUsername = textBox2.Text.ToString();
string AppPassword = textBox1.Text.ToString();
//- Hashed-V-
byte[] salt;
new RNGCryptoServiceProvider().GetBytes(salt = new byte[16]);
var pbkdf2 = new Rfc2898DeriveBytes(AppPassword, salt, 10000);
byte[] hash = pbkdf2.GetBytes(20);
byte[] hashBytes = new byte[36];
Array.Copy(salt, 0, hashBytes, 0, 16);
Array.Copy(hash, 0, hashBytes, 16, 20);
string savedPasswordHash = Convert.ToBase64String(hashBytes); // <-- see ' https://stackoverflow.com/questions/4181198/how-to-hash-a-password ' for the part on comparing the recalculated
//-
SqlConnection con = new SqlConnection();
con.ConnectionString = ("Data Source=DESKTOP-PGHMM6M;Initial Catalog=LocalUsers;Integrated Security=True");
con.Open();
var cmd = new SqlCommand(#"SELECT Username, Hash FROM App_Users WHERE (Hash = #Hash");
cmd.Connection = con;
savedPasswordHash = cmd.ExecuteScalar() as string;
if (cmd.ExecuteNonQuery() > 0) {
MessageBox.Show(" Query successful..something matched.. ");
//change page.. load a profile?
}
However, I am getting the error:
'Must declare the scalar variable "#Hash".'
I've searched around but I'm not sure what the next step for exactly what I am trying to do is.. Sorry this is probably a bad question, sql-wise. I think it has something to do with an adapter?

You didn't pass a value for the #Hash parameter in the query. And you should also check for the user name in the query or else the login attempt is successful if any login uses the given password.
Try something like:
...
var cmd = new SqlCommand(#"SELECT Username, Hash FROM App_Users WHERE Hash = #Hash AND Username = #Username");
cmd.Connection = con;
cmd.Parameters.Add("#Hash", SqlDbType.VarChar, 48).Value = savedPasswordHash;
cmd.Parameters.Add("#Username", SqlDbType.NVarChar, 32).Value = AppUsername;
if (cmd.ExecuteNonQuery() > 0) {
...
This assumes, that App_Users.Hash is a VARCHAR(48) and App_Users an NVARCHAR(32). You may need to change it to match the data types you're actually using.

Related

ASP.NET and SQL Server : update last record with dynamic values

I'm retrieving an HTTP response which I am deserializing the values into an Azure SQL database. I cannot find any way to format the SQL command to UPDATE string variables into the last record of the table. The intent is to overwrite the last record with each new token to avoid database maintenance requirements. I can statically write a value as in the example below, but I need it to be dynamically passed by variable which seems to throw off the syntax or command execution for some reason. No errors or exceptions are thrown - it just doesn't do anything.
Does anyone have any ideas on how I could go about accomplishing this? The SQL specific code is listed below for reference.
dynamic access = JsonConvert.DeserializeObject(response.Content);
string accessToken = access.access_token;
string timestamp = centralTime.ToString();
System.Data.SqlClient.SqlConnection connect = new System.Data.SqlClient.SqlConnection(connectionString);
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand();
command.CommandType = System.Data.CommandType.Text;
// this works as needed to insert a new record where required, but builds record counts over time
// command.CommandText = #"INSERT INTO AccessTokens (Token, LastRefreshDate) VALUES (#Token, #LastRefreshDate)";
// command.Parameters.AddWithValue("#Token", accessToken);
// command.Parameters.AddWithValue("#LastRefreshDate", centralTime);
// I've tried as many variations as possible based on what's available online upon searching; these are two examples that don't work
// command.CommandText = #"UPDATE TOP 1 * FROM AccessTokens (Token, LastRefreshDate) VALUES (#Token, #LastRefreshDate)";
// command.CommandText = #"UPDATE AccessTokens SET Token = " + accessToken + " , LastRefreshDate = " + timestamp;
// this will update the record with the new value, but it's static
command.CommandText = #"UPDATE AccessTokens SET Token = 12345";
string test = "test";
// attempting to update with a string variable does not work, which is the desired outcome in order to maintain only one record with a dynamically changing value over time
// command.CommandText = #"UPDATE AccessTokens SET Token = " + test;
command.Connection = connect;
connect.Open();
command.ExecuteNonQuery();
connect.Close();
The understanding is that you need to continually update the last token inserted into your AccessToken table. Assuming your LastRefreshDate is unique enough into the milliseconds, this should look like
command.CommandText = #"UPDATE AccessTokens set Token = #Token where LastRefreshDate = (select Max(LastRefreshDate) from AccessTokens)"
Ideally, if this token exists with a bunch of other access tokens you would have a unique ID in that AccessToken where it's restricted to a particular id like:
command.CommandText = #"UPDATE AccessTokens set Token = #Token where LastRefreshDate = (select Max(LastRefreshDate) from AccessTokens and ID=#ID) and ID=#ID"

SQL Server table column value not update when hit by api provider

I am using an API for recharge portal and provide them a page for recharge status update and the hit my page url with some query string parameter. Then I read the query string and update table. URL hit is showing in my IIS log but table is not updated but when I'm hitting manually same it has been update. I'm unable to find out reason behind.
Here is the url they hit
mypage.aspx?status=success&trans_no=12373&client_key=12368754&rech_no=9235155800&amount=10&opr_code=1&success_id=UEH1708181415290215&msg=recharge%20request%20was%20succeeded.
and here is the code of my page load event
string status = Request.QueryString["status"];
string apiRef = Request.QueryString["trans_no"];
string refId = Request.QueryString["client_key"];
string oRefId = Request.QueryString["success_id"];
if (status == "success")
status = "Success";
SqlConnection conn = new
SqlConnection(WebConfigurationManager.AppSettings["ConnString1"]);
SqlCommand cmd = new SqlCommand("UPDATE mytable SET status=#status
,oreference_id= #oRefId ,udate=GETDATE() WHERE ureference_id= #refId AND
areference_id= #apiRef", conn);
cmd.Parameters.AddWithValue("#status", status);
cmd.Parameters.AddWithValue("#oRefId", oRefId);
cmd.Parameters.AddWithValue("#refId", refId);
cmd.Parameters.AddWithValue("#apiRef", apiRef);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
Any help will be appreciated. Thanks in advance.
You can try this code i hope it will work for you
string status = Request.QueryString["status"];
string apiRef = Request.QueryString["trans_no"];
string refId = Request.QueryString["client_key"];
string oRefId = Request.QueryString["success_id"];
if (status == "success")
status = "Success";
SqlConnection conn = new SqlConnection(WebConfigurationManager.AppSettings["ConnString1"]);
conn.Open();
SqlCommand cmd = new SqlCommand("UPDATE mytable SET status=#status ,oreference_id= #oRefId ,udate=GETDATE() WHERE ureference_id= #refId AND areference_id= #apiRef", conn);
cmd.Parameters.AddWithValue("#status", status);
cmd.Parameters.AddWithValue("#oRefId", oRefId);
cmd.Parameters.AddWithValue("#refId", refId);
cmd.Parameters.AddWithValue("#apiRef", apiRef);
cmd.ExecuteNonQuery();
conn.Close();

Like and = operater is not working together in signal query

I am using sap.net web form. In this web form i have a text and a button. user enter name or id and hit search button. Searching with id is working fine but with name it is not working.
What i am missing here help me out please.
String Status = "Active";
String BDstring = ConfigurationManager.ConnectionStrings["CS"].ConnectionString;
using (SqlConnection conn = new SqlConnection(BDstring))
{
try
{
String query = "SELECT * from Driver where(Name LIKE '%' + #search + '%' OR DriverID = #search) AND Status = 'Active'";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("#search", SearchTextBox.Text);
conn.Open();
SqlDataReader SDR = cmd.ExecuteReader();
DataTable DT = new DataTable();
if (SDR.HasRows)
{
DT.Load(SDR);
GridView.DataSource = DT;
GridView.DataBind();
}
}
catch (SqlException exe)
{
throw exe;
}
}
}
The code is generating an exception. The fact that you're unaware of this indicates that you have "error handling" somewhere in your system that is, in fact "error hiding". Remove empty catch blocks, or pointless catch blocks such as the one in your question that just destroys some information in the exception and re-throws it. Those aren't helping you.
The actual problem is that the DriverID column is int and your parameter is varchar. So long as the varchar contains a string that can be converted to a number (which is the direction that the conversion happens in due to precedence), the query is well-formed.
As soon as the parameter contains a string that cannot be implicitly converted to a number, SQL Server generates an error that .NET turns into an exception.
For your LIKE variant, you're forcing a conversion in the opposite direction (numeric -> varchar) since LIKE only operates on strings. That conversion will always succeed, but it means that you're performing textual comparisons rather than numeric, and also means there's no possible index usage here.
I'd suggest that you change your C# code to attempt a int.TryParse on the input text and then uses two separate parameters to pass strings and (optionally) their numeric equivalent to SQL Server. Then use the appropriate parameters in your query for each comparison.
Something like:
String Status = "Active";
String BDstring = ConfigurationManager.ConnectionStrings["CS"].ConnectionString;
using (SqlConnection conn = new SqlConnection(BDstring))
{
String query = "SELECT * from Driver where(Name LIKE '%' + #search + '%' OR " +
"DriverID = #driverId) AND Status = 'Active'";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.Add("#search", SqlDbType.VarChar,50).Value = SearchTextBox.Text;
cmd.Parameters.Add("#driverId", SqlDbType.Int);
int driverId;
if(int.TryParse(SearchTextBox.Text, out driverId))
{
cmd.Parameters["#driverId"].Value = driverId;
}
conn.Open();
SqlDataReader SDR = cmd.ExecuteReader();
DataTable DT = new DataTable();
if (SDR.HasRows)
{
DT.Load(SDR);
GridView.DataSource = DT;
GridView.DataBind();
}
}
"SELECT * from Driver where (Name LIKE '%" + #search + "%'
OR DriverID = '" + #search + "' ) AND Status = 'Active'";
how about this?

Why is this SQL statement giving me an invalid column name error?

I'm trying to use an SQL select statement to read from a database to validate a login form. The problem I'm having is its telling me its an invalid column name.
SELECT * FROM users
WHERE [username] = #theusername
AND [password] = #thepassword
where #theusername is a parameratized value of "Rymo_18", and the password is, for the sake of argument, "password".
The errors I get are:
Invalid column name 'Rymo_18'.
Invalid column name 'password'
Don't know why I'm getting those errors. I've tried swapping the values around the = sign, tried using values directly (username = "Rymo_18") and all other matters of fiddling to fix it, and I've had no luck. There are no other tables called 'user' within my Database.
EDIT: Here's the code as it appears in the C# I'm using:
string user = unametext.Text;
string pword = pwordtext.Text;
string connectionstring = WebConfigurationManager.ConnectionStrings["elmtreeconnect"].ConnectionString;
SqlConnection myconnection = new SqlConnection(connectionstring);
myconnection.Open();
string query = "SELECT * FROM users WHERE (username= #theusername OR email = #theusername) AND password = #thepassword";
SqlCommand attemptLogin = new SqlCommand(query, myconnection);
attemptLogin.Parameters.AddWithValue("#theusername", user);
attemptLogin.Parameters.AddWithValue("#thepassword", pword);
SqlDataReader rdr = attemptLogin.ExecuteReader();
if (rdr.HasRows)
{
Session["user"] = rdr["username"].ToString();
Session["id"] = rdr["id"].ToString();
Session["type"] = rdr["accountType"].ToString();
Response.Redirect("loginsuccess.aspx");
}
else
{
unametext.Text = "";
pwordtext.Text = "";
statusLabel.Text = "Login failed. Please try again, or contact info#elmtree.co.uk for assistance";
}
Thanks for the help!
string query = "select 1 from users where username=#theusername and password=#password";
...
if(rdr.Read()){
...
}
exists should be used in if exists(select...)

ExecuteReader returns no results, when inspected query does

Consider the following code:
StringBuilder textResults = new StringBuilder();
using(SqlConnection connection = new SqlConnection(GetEntityConnectionString()))
{
connection.Open();
m.Connection = connection;
SqlDataReader results = m.ExecuteReader();
while (results.Read())
{
textResults.Append(String.Format("{0}", results[0]));
}
}
I used Activity Monitor within Sql Server Mgmt Studio on the database to inspect the exact query that was being sent. I then copied that query text to a query editor window within SSMS, and the query returned the expected results. However, SqlDataReader results is always empty, indicating "The enumeration returned no results."
My suspicion is that somehow the results are not being returned correctly, which makes me think there's something wrong with the code above, and not the query itself being passed.
Is there anything that would cause this in the code above? Or something I've overlooked?
EDIT:
Here is the query as indicated by the SQLCommand object:
SELECT DISTINCT StandardId,Number
FROM vStandardsAndRequirements
WHERE StandardId IN ('#param1','#param2','#param3')
ORDER BY StandardId
Here is the query as it appears in Activity Monitor:
SELECT DISTINCT StandardId,Number
FROM vStandardsAndRequirements
WHERE StandardId IN ('ABC-001-0','ABC-001-0.1','ABC-001-0')
ORDER BY StandardId
The query is working against a single view.
When I ran the second query against the database, it returned 3 rows.
The SqlDataReader indicates 0 rows.
try to use Sqldata adapter instead of sqldatreader.
StringBuilder textResults = new StringBuilder();
using (var conn = new SqlConnection(GetEntityConnectionString())))
{
using (
var cmd = new SqlCommand(
"SELECT DISTINCT StandardId,Number" +
"FROM vStandardsAndRequirements " +
"WHERE StandardId IN (#param1,#param2,#param3)" +
"ORDER BY StandardIdl"
, conn))
{
var dSet = new DataSet();
var dt = new Datatable();
var da = new SqlDataAdapter(cmd);
cmd.Parameters.Add("#param1", SqlDbType.VarChar, 50).Value = "ABC-001-0";
cmd.Parameters.Add("#param2", SqlDbType.VarChar, 50).Value = "ABC-001-0.1";
cmd.Parameters.Add("#param3", SqlDbType.VarChar, 50).Value = "ABC-001-0";
try
{
da.Fill(dSet);
dt = dSet.Tables[0];
foreach(Datarow a in dt.Rows)
{
textResults.Append(a["StandardId"].tostring()).AppendLine();
}
Messabox.Show(textResults.tostring);
}
catch (SqlException)
{
throw;
}
finally
{
if (conn.State == ConnectionState.Open) conn.Close();
}
}
}
Regards.
Are you sure it is
WHERE StandardId IN ('#param1','#param2','#param3')
instead of this?
WHERE StandardId IN (#param1,#param2,#param3)
Parameters should not be quoted, not in the SQLCommand object.
Very nice behavior I've observed
I looked for errors in code:
... dr = command.ExecuteReader() ... If dr.Read Then ...
and found that 'dr.Read' works fine, but...
when I mouseover on 'dr', to lookup for data, return values disappeared !
Check your connection string and make sure you are not connecting as a user instance.
http://msdn.microsoft.com/en-us/library/ms254504.aspx