Conversion failed when converting the varchar to int mvc C# - c#

I'm getting a runtime error
Conversion failed when converting the varchar to int
with this code:
public ActionResult Index(Model1 m)
{
string q = "select username, password from login where username=#username and password=#password ";
con.Open();
SqlCommand cmd = new SqlCommand(q, con);
cmd.Parameters.AddWithValue("#username", m.username).ToString();
cmd.Parameters.AddWithValue("#password", m.password).ToString();
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()) // getting error at this point
{
return RedirectToAction("upload");
}
else
{
ViewData["Message"] = "invalid username or password";
}
con.Close();
return View();
}

Everything you need to do is in this answer including using Entity Framework instead of this ancient, long winded way of running SQLs that doesn't promote good OO design practices (separation of concerns between your business logic layer in your controller and your data access layer)
At the very least, take a look at switching to using Dapper for your data access - it'll make your code cleaner and your life a lot easier
Use the first linked answer to develop a class that salts and hashes your passwords and stores the hashes rather than the plain text passwords, and call on it ensuring your passwords are held securely. Storing passwords in plaintext is the reason why services like HaveIBeenPwned need to exist; people reuse passwords and when you store your passwords in plaintext and your system is hacked it will reveal a nice easy lookup of username:password that can be used elsewhere that has been broken into and all the hacker has is the username. Part of that is the users fault for reusing a password, but mostly your fault for not holding their details securely. Please prioritize this

Related

Create Login and Validating Users in Asp.net

I have created login page and i want to verify the users if they have access or not. I have done most of the work but just need couple of things here:
1) if user is validated, then i want to redirect to Home.aspx page
2) After the user is validated i want to be able to save the user id in a session so they don't have to login every time if they are redirected to another page.
Basically, once they login successfully they should be able to navigate other pages in the application. thanks.
here is the code behind:
protected void ValidateUser3(object sender, EventArgs e)
{
int userId = 0;
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("Validate_User"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Username", txtUID.Text.Trim());
cmd.Parameters.AddWithValue("#Password", txtPWD.Text.Trim());
cmd.Connection = con;
con.Open();
userId = Convert.ToInt32(cmd.ExecuteScalar());
con.Close();
}
switch (userId)
{
case -1:
logLbl.Text = "Username and/or password is incorrect.";
break;
case -2:
logLbl.Text = "Account has not been activated.";
break;
}
}
}
Here is my stored proc:
ALTER PROCEDURE [dbo].[Validate_User]
#Username NVARCHAR(20),
#Password NVARCHAR(20)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #UserId INT, #LastLoginDate DATETIME
SELECT #UserId = UserId, #LastLoginDate = LastLoginDate
FROM myTable WHERE Username = #Username AND [Password] = #Password
IF #UserId IS NOT NULL
BEGIN
IF NOT EXISTS(SELECT UserId FROM [Main].[UserActivation] WHERE UserId = #UserId)
BEGIN
UPDATE myTable.[dbo].[UserProfile]
SET LastLoginDate = GETDATE()
WHERE UserId = #UserId
SELECT #UserId [UserId] -- User Valid
END
ELSE
BEGIN
SELECT -2 -- User not activated.
END
END
ELSE
BEGIN
SELECT -1 -- User invalid.
END
END
First up I'd look at tightening that security. Don't save passwords in your database, not even hashed ones. And follow krillgar's advice in the comments to your question :)
What you want to do with each user account is create a unique salt code - a random value, with a minimum of 8 in length (the more the better naturally): See here for creating a salt code. You want to save that in your database in the users table. So you'll have something like a table structure like: UserId, UserName, PassString, SaltCode, Active
Pick a Hashing method; MD5 or SHA1 are typical examples. When the password is created you take the username, merge it into the password, add your salt code then Hash it. This will create a unique string - that's what you save into your database in the PassString field.
So when someone logs in you take the username and password, look up the user record, get the salt code. Hash it all together then compare the two hashed strings.
Check out this section on Stack Overflow: How to hash a password
This makes your passwords irreversible without all segments of the data in other words; the password the user enters to login is the missing key to the puzzle. If someone is somehow able to get the data out of your table they'll have to a ton of work to crack a user's account.
so to now answer your actual question :)
Just like you have with your Stored Procedure, when the user is successfully matched return a value such as 1. I would suggest you keep your return codes and userid value separate so there's less ambiguity in your code. You got a choice with your SP, you can either return the userid back in with the return code on a Select statement ie Select 1, #UserId or you can use an OUTPUT parameter, here's a fairly decent example: Using stored procedure output parameters in C# (I'd favour the latter).
Now working with what you've got (and by that I mean, not telling you to go off an use System.IdentityModel.Service, UserPrinciple and the likes)...
Once that successful login has been acknowledged by your SP, use a session variable in the following manner, Session variables are kept server side so unless your server is compromised you'll be ok:
Session["UserId"] = userId;
Response.Redirect("Home.aspx");
Now on pages like Home.aspx you just need some code along the lines of;
bool userLoggedIn = false;
if (Session["User"] != null) //check the session variable is actually valid
{
if (!String.IsNullOrEmpty(Session["User"]))
{
userLoggedIn = true;
}
}
if (!userLoggedIn)
{
Response.Redirect("login.aspx");
}
Though it would be a lot wiser to create a class in the App_Code folder to handle this, last thing you want is duplicated code all over your site.
The issue you'll run into is giving user's rights. I'm not clear from your question but I got the impression you wanted a binary login, ie: if a user is authenticated they have access, plain and simple. If you're after segmented security; controlling what each user can or cannot do then you need to be looking down the route of Claims based security, here's an example of that to get you thinking: http://www.codeproject.com/Articles/2905/Role-based-Security-with-Forms-Authentication
I hope that helps and wasn't too long a read :)

Trouble querying SQL Server database via C#

I have created a web form using a custom login control to access a local SQL Server database. The database contains a table named Employees with various info about the employee, however, the relevant columns for my question are EmployeeID (primary key), Username, and Password.
I am trying to query the database using the username and password entered in the login control to retrieve the EmployeeID. An exception is thrown when trying ExecuteScalar(). The exception states that 'Employees' is an invalid object name, so I suspect my problem is the connection string. I retrieved the connection string by viewing the properties of the database in SQL Server 2014 Management Studio, which is where I also created the db. Another guess is that authentication when connecting to the db. I'm not really sure though, so can someone help please?
string connectionString = "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\Users\\Joshua\\AppData\\Local\\Microsoft\\VisualStudio\\SSDT\\SignProDatabase\\SignProDatabase.mdf;Integrated Security=True;Connect Timeout=30";
string query = "select EmployeeID from Employees where Username = 'user' and Password = 'pass'";
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(query, connection);
try
{
object test = cmd.ExecuteScalar();
Console.WriteLine(test.ToString());
}
catch(Exception err)
{
Console.WriteLine("Exception Message: " + err);
Console.ReadLine();
}
As Martin mentioned in the comments, the account that is running the application will need access to the server and database, as well as select permission on the Employees table. Also, if the code provided is not just for example then for security reasons you shouldn't be storing the actual passwords in your database and you will want to validate the input to protect against SQL injection attacks.

Sending authentication information to SQL Server isn't working (C#)

I already asked about a similar issue to this one but I've narrowed it down to my problem and I've been working on this for hours and unable to figure this out.
Basically, I have a visual studio wep application and I'm trying to use a login page and sql server database to validate user credentials. The user enters a string for username and password on the log-in screen which gets sent here on the code behind:
private bool ValidateUser(string userName, string passWord)
{
SqlConnection conn;
SqlCommand cmd;
string lookupPassword = null;
// Consult with your SQL Server administrator for an appropriate connection
// string to use to connect to your local SQL Server.
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["databaseConnect"].ConnectionString);
conn.Open();
// Create SqlCommand to select pwd field from users table given supplied userName.
cmd = new SqlCommand("Select Password from Users where User=#userName;", conn);
cmd.Parameters.Add("#userName", System.Data.SqlDbType.VarChar, 25);
cmd.Parameters["#userName"].Value = userName;
lookupPassword = (string)cmd.ExecuteScalar();
// If no password found, return false.
if (null == lookupPassword)
{
return false;
}
private void cmdLogin_ServerClick(object sender, System.EventArgs e)
{
if (ValidateUser(txtUserName.Value,txtUserPass.Value) )
(logs in)
}
The application is connected a table in a database, which currently holds one test item, as shown here: http://i.imgur.com/YFOQYKm.jpg
However, when I enter "test" as username and "password" as password, it doesn't accept the log-in.
I tried to include only the relevant parts of my code to make it more clear for anybody trying to answer the question but here's a few comments about my problem:
-When I set if (null == lookupPassword) to "return true" instead of "return false" the application allows logins. Which means lookupPassword is still null after "lookupPassword = (string)cmd.ExecuteScalar();"
-The application works fine when I change if(ValidateUser(txtUserName.Value,txtUserPass.Value)) to if(userName=test and passWord=password). So the problem is not with the actual act of logging into the application, it just isn't finding the SQL Server credentials to be true.
-"databaseConnect" is working elsewhere on the application, so that is not the issue.
-The application is not breaking when I submit the login credentials, it is simply not accepting them as correct.
Going off that, it seems to me that the problem comes from these four lines:
cmd = new SqlCommand("Select Password from Users where User=#userName;", conn);
cmd.Parameters.Add("#userName", System.Data.SqlDbType.VarChar, 25);
cmd.Parameters["#userName"].Value = userName;
lookupPassword = (string)cmd.ExecuteScalar();
Does anybody see where the problem might be for me? I'm very new to programming so please keep the answers as simple as possible please. Thank you in advance for any help. :)
This table design is using several reserved words in SQL Server. If you cannot modify this schema, you can update your query as follows:
SELECT [Password] FROM [Users] WHERE [User] = #Username
That being said, storing passwords in plaintext is a horrible security practice. Passwords should never be stored encrypted or as plaintext, they should be hashed using a salt to help avoid rainbow tables from cracking your password. I would look into the suggestion from #Richard regarding Rfc2898DeriveBytes. You can also search Google or Bing for using salt and SHA256.

How to implement a password change functionality with Oracle and a .Net client?

I'm using Oracle users to authenticate username and password for a .Net application. Right now I'm working on the password change function. The database has a custom password validation, so if you try to change a users password and you provide an invalid password, Oracle returns multiple errors.
The first error is always "ORA-28003: password verification for the specified password failed", and then it rises one error for each failed validation. This is shown correctly when I try to change a user's password from the Toad client.
However, when I do this from my application, the OracleException that is raised only returns the first error, and therefore I'm not able to show the user what's invalid about the new password he provided, which is a requirement for the application. So how should I aproach this?
For starters, don't use the OpenWithNewPassword method. Not only does it have known issues with with various versions of ODP.net and the DB, but it forces you to have two different branches of code when you only need one - IIRC it doesn't work if the user's password has already expired.
Instead the basic logic works like this:
Make sure you can authenticate with the user's old account and password
If you're successful, close that connection and open a separate account that has no access other than exec privs on a ChangePassword stored procedure.
Here's the code:
protected void BtnChangePassword_Click(object sender, EventArgs e)
{
String connectionStringFormat = "Data Source={0};User Id={1};Password={2};pooling=false;";
if (Page.IsValid)
{
Boolean hasHasError = false;
String connectionString = String.Format(
connectionStringFormat,
IptDatabase.Text,
IptUserName.Text,
IptOldPassword.Text);
OracleCommand cmd = new OracleCommand();
using (cmd.Connection = new OracleConnection(connectionString))
{
try
{
cmd.Connection.Open();
}
catch (OracleException ex)
{
//allow to continue if the password is simply expired, otherwise just show the message
if (ex.Number != 28001)
{
ShowErrorMessage(ex.Message);
hasHasError = true;
}
}
if (!hasHasError)
{
//successful authentication, open as password change account
cmd.Connection.Close();
cmd.Connection.ConnectionString = ConfigurationManager.ConnectionStrings[IptDatabase.Text].ConnectionString;
cmd.Connection.Open();
cmd.CommandText = "SysChangePassword";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("username", IptUserName.Text);
cmd.Parameters.Add("newpassword", IptPassword.Text);
try
{
cmd.ExecuteNonQuery();
ShowInfoMessage("Password Changed");
}
catch (OracleException ex)
{
ShowErrorMessage(ex.Message);
}
}
}
}
In it's simplest form, the proc executes 'alter user identified by and would be similar to the one documented here: http://www.adp-gmbh.ch/ora/plsql/change_password.html. However the dbms_output lines don't do you much good so you could throw custom exceptions instead:
create or replace procedure SysChangePassword(
pUserName in varchar2,
pPassWord in Varchar2) as
begin
-- Check for system users here and reject
if upper(pUserName) in ('SYS','SYSTEM') then
raise_application_error(-20012, 'not allowed');
else
execute immediate 'alter user '||pUserName||' identified by ' ||
pPassWord;
end if;
exception --this isn't necessary if you'd rather examine and handle the specific exceptions on the .net side
when others then
raise_application_error(-20012, sqlerrm);
end;
/
The schema that owns this procedure needs 'alter any user' privleges. For safety's sake, your app should connect as a separate user that only has execute privs on this proc. Rather
Why don't you wrap the logic in a stored procedure? It would call the Oracle password validation functions, then you parse the results as needed, and return whatever messages you want back to the .net client?
Why don't you use a Regular Expression Validator control if writing for ASP.NET, Or Regex.IsMatch(...) Function if writing desktop applications? Why you have to go to the server first to get the error generated. you have strong password policy, and you can restrict the user on client side.

Load data from database in _layout.cshtml

I am creating a web application using ASP.NET MVC 4.
I want to display the user's nickname on all of pages, so I have to load it in _layout.cshtml.
Please note that I'm storing user's nickname manually. (In my own database and my own tables.)
I can add user's User name by Membership.GetUser().UserName, but I want to load his nickname from database and show it in _layout.cshtml.
How to do that?
Let me give a simple solution for what you want:
write an action in a controller (mine is CommonController):
public ActionResult NickName()
{
SqlConnection cn = new SqlConnection(cnstr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
cn.Open();
SqlDataReader dr = cmd.ExecuteReader();
string nickName = string.Empty;
while (dr.Read())
{
nickName = dr["nick_Name"].ToString();
}
dr.close()
return Content(nickName);
}
put the below line in everywhere you want in _Layout:
nickname = #{Html.RenderAction("NickName", "Common");}
Finished!
Thanks to #SergRogovtsev for recommending:
nickname = #Html.Action("NickName", "Common")
first asked:
Are you using entity framework?
You can use partial views in _Layout either using EF or ADO.
If you mean you can't access aspnet_membership table by using entity framework, you should ask your question in another way!
let me know more about your problem by giving some sample of your code.
I would advise you to upon logging in, store the username in a session variable (which is done by accessing the Session object, which implements a key=value pair architecture allowing you to store and retrieve your data at will). It's a drag on performance to have to make a database call for EVERY page that loads, and a single nickname string variable in session won't take up that much space on your server.
As far as loading the variable you could use the code posted by Vahid, but I would recommend you if your site is still in its infancy to take the extra time to learn and implement Entity Framework. It is cleaner, easier and Microsoft is really pushing data connection management in that direction.
I have used a combination of Mr_Creostoe and Vahid answers.
I am saving nickname in a session (as Mr_Cresotoe said), and if there isn't such session (for example, if user ticked remember me checkbox and is visiting after many time), I'll create that session using RenderAction. (As Vahid said).
Thank you guys!

Categories