How to connect to mysql without using plain text? - c#

I'm trying to make it so i can use username/password i've set in the properties/settings to connect to mysql as i dont want to store mysql details in plaintext here what i'm using but not sure how to go about reading the username/password from properties, Could anyone help? thanks
private void PassTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
try
{
string MyConnection = "datasource=localhost;port=3309;username=user;password=pass123";
MySqlConnection MyConn = new MySqlConnection(MyConnection);
MySqlCommand MyCommand = new MySqlCommand("select * from applogin.users where UserId='" + this.UserTextBox.Text + "' and UserPassword='" + this.PassTextBox.Text + "' ;", MyConn);
MySqlDataReader MyReader;
recby = UserTextBox.Text;
MyConn.Open();
MyReader = MyCommand.ExecuteReader();
int count = 0;
while (MyReader.Read())
{
Console.WriteLine(MyReader[count]);
count++;
}
if (count == 1)
{
MessageBox.Show("Accepted, Welcome!");
this.Hide();
Form5 f5 = new Form5();
f5.ShowDialog();
}
else if (count > 1)
{
MessageBox.Show("Duplicate Username and passwor.\nAccess denied.");
}
else
{
MessageBox.Show("Username and password is incorrect.\nPleas try again.");
}
MyConn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

class DBConnect
{
private MySqlConnection connection;
private string server;
private string database;
private string uid;
private string password;
//Constructor
public DBConnect()
{
Initialize();
}
//Initialize values
private void Initialize()
{
server = "localhost";
database = "connectcsharptomysql";
uid = "username";
password = "password";
string connectionString;
connectionString = "SERVER=" + server + ";" + "DATABASE=" +
database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
connection = new MySqlConnection(connectionString);
}
//open connection to database
private bool OpenConnection()
{
bool flag=false;
if (this.OpenConnection() == true)
{
//Create Mysql Command
MySqlCommand cmd = new MySqlCommand(query, connection);
//ExecuteScalar will return one value
Count = int.Parse(cmd.ExecuteScalar()+"");
flag=true;
//close Connection
this.CloseConnection();
return flag;
}
else
{
return flag;
}
}
}

I would rather recommend to read password from an environment variable instead of hardcoding it in the code.

This is a broad topic.
Mainly, it is "how to store a 'secret' well?"
I'll give some hints.
First, in dotnet CORE, there is new stuff.
https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1&tabs=windows
That is for local development, BUT AT LEAST forces you to think about where that secret is being stored.
Using .ini, .config, .txt files and keeping a secret in plain text IS NOT secure for production scenarios.
So then you have to start thinking about "how is my code deployed?"
If you are deploying to Azure, there is Azure Key Vault.
If you are deploying to a machine/VM, then you have to consider something more robust, like Hashicorp Vault.
But you're going to get a few "quick fix" answers. You need to really consider where you keep this secret for your deployed code.

If I read your question correctly, you don't care about the connection string userid/password but about the users login credentials.
This is based on your line:
MySqlCommand MyCommand = new MySqlCommand("select * from applogin.users where UserId='" + this.UserTextBox.Text + "' and UserPassword='" + this.PassTextBox.Text + "' ;", MyConn);
And it appears you are asking about how to encrypt the password so that someone can't monitor the communication. Of course, your connection string is already an issue, but back to what I believe is your question.
It's not clear if you are using the actual user name and password as entered or not. If so, the easiest option is to use 1 way encryption - and only store the encrypted values. Then your code would get the value of the textbox and encrypt it. Then execute a query with the encrypted value (preferably with those encrypted values as parameters, not inline text.)
The result would be a query that might look like:
select * from applogin.users where UserId='kajsdf09823rcfs98dsjssdf' and UserPassword='j;las9onq;p;9wf;kjadf' ;
and written correctly (assuming you have a method named encrypt that implements whatever encryption you choose):
userId = new SqlParameter("#userName", encrypt(this.UserTextBox.Text));
userpw = new SqlParameter("#userPw", encrypt(this.PassTextBox.Text));
cmd.Parameters.Add(userId);
cmd.Parameters.Add(userpw );
cmd.CommandText = "select * from applogin.users where UserId=#userName and UserPassword=#userPw ;";
There are other great suggestions as well, I encourage you to follow up on those as well.

Related

How can i pass a value to a label from a database based on the users details

I have a login table with each user having different roles eg Staff, Admin.
I can have the user log in sucessfully with their username displaying between pages on the console application.
I am trying to Add in a new label beside the username label so upon login the next page will have something like this Admin: Johny or Staff: Bob
What i have tried to do is Change the query to:
"SELECT Role From User_Table WHERE eb_number='" + usernametxt.Text + "' and Password = '" + textBox1.Text + "'",con);
but this does not work either.
private void loginbtn_Click(object sender, EventArgs e)
{
//GRANT ACCESS TO THE DATABASE WITH USERNAME AND PASSWORD WHICH IS STORED IN THE DATABASE.
SqlConnection con = new SqlConnection(conString);
con.Open();
if (con.State==System.Data.ConnectionState.Open)
{
SqlDataAdapter sda = new SqlDataAdapter("SELECT Count(*) From User_Table WHERE eb_number='" + usernametxt.Text + "' and Password = '" + textBox1.Text + "'",con);
DataTable dt = new DataTable();
sda.Fill(dt);
if (dt.Rows[0][0].ToString() == "1")
{
this.Hide();
Main ss = new Main(usernametxt.Text); //usernametxt is passed in to prevent error
ss.Show();
MessageBox.Show("Logged in sucessfully");
}
else
{
MessageBox.Show("Incorrect Username/Password Combination. Try Again");
}
}
}
Main.cs
public Main(string Username/*, string Role*/) //passing username values
{
InitializeComponent();
Username_lbl.Text = Username; //Displaying username
//Main_Role_lbl.Text = Role;
At he minute my code Just lets me log in and out reading the username and passwords. I am unsure if i can add in to search for the Role for the username in the SQL query this way? What i expected it the code to do was have a login like Admin: Johny or Staff: Bob
Here you go something similar to your implementation:
private void loginbtn_Click(object sender, EventArgs e)
{
var conString = "ReplaceWithMyConnectionString";
string userRole = null;
using (var con = new SqlConnection(conString))
{
con.Open();
var cm = con.CreateCommand();
cm.CommandType = System.Data.CommandType.Text;
cm.CommandText = "SELECT TOP 1 Role FROM User_Table WHERE eb_number = #eb_number AND and Password = #Password";
cm.Parameters.Add(new SqlParameter("#eb_number", System.Data.SqlDbType.VarChar, 50) { Value = usernametxt.Text });
cm.Parameters.Add(new SqlParameter("#Password", System.Data.SqlDbType.VarChar, 50) { Value = textBox1.Text });
using (var reader = cm.ExecuteReader(System.Data.CommandBehavior.SingleRow))
{
if (reader.Read())
{
userRole = reader["Role"].ToString();
}
}
}
if (userRole != null)
{
this.Hide();
Main ss = new Main(usernametxt.Text, userRole); //usernametxt is passed in to prevent error
ss.Show();
MessageBox.Show("Logged in sucessfully");
}
else
{
MessageBox.Show("Incorrect Username/Password Combination. Try Again");
}
}
There are a few things that are different, I'll explain the reason behind them:
I replaced with parameters the string concatenation you were doing on your SQL. This is to avoid SQL injection. Have you wondered
what would happen if the user enters the character ' in the
username or password textboxes? there's more to this, please research this subject.
I'm instantiating your connection inside a using statement. This will make sure that your connection is closed (disposed) when we are done with the db stuff.
Replaced the DataAdapter/DataTable with a leaner SqlCommand/SqlDataReader classes.
I separated the logic in a way that the connection can be closed asap, and is not being interrupted by the call to MessageBox.Show().
Also, and very important, never store your passwords as clear text in the database, please do some research about hashing functions and why they should be used in this context.
I hope this helps.

C# store data error in Microsoft Access database

private void okbtn_Click(object sender, EventArgs e)
{
OleDbConnection conn = new OleDbConnection();
conn.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Desktop\GameMuseumManagementSystem.accdb";
try
{
conn.Open();
String Name = txtName.Text.ToString();
String Email = txtEmail.Text.ToString();
String Password = txtPassword.Text.ToString();
String my_query = "INSERT INTO Member(Member_Name,Member_Password,Member_Email)VALUES('" + Name + "','" + Email + "','" + Password + "')";
OleDbCommand cmd = new OleDbCommand(my_query, conn);
cmd.ExecuteNonQuery();
MessageBox.Show("Data saved successfuly...!");
}
catch (Exception ex)
{
MessageBox.Show("Failed due to" + ex.Message);
}
finally
{
conn.Close();
}
}
I am coding for the member registeration for a guest to use it. I have 3 pieces of data, member_name, member_ID, and password. I coded this and I get an error. My Visual Studio is connected to my MS Access database via the tools, after I write this code, the data can't be stored in Access, what should I do now? Any suggestion?

Retrieve data from database using C#

I'm trying to retrieve data from database in Microsoft visual studio 2013 . I am totally lost whether I am already able to connect to the database or not and I am not sure how to retrieve data using c# as I am totally new to c#.
I am also not sure where I should put the static void main method statement before or after connectDB() method.
private void connectDB()
{
// server = "172.20.129.159";
database = "eyetracker";
server = "localhost";
// uid = "ogamaaccess";
// password = "ogama";
uid = "root";
password = "root";
string connectionString;
connectionString = "SERVER=" + server + ";" + "DATABASE=" + database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
c = new MySqlConnection(connectionString);
Console.WriteLine("Connected to database");
}
private bool OpenConnection()
{
try
{
c.Open();
Console.WriteLine("Connection Opened.");
return true;
}
catch (MySqlException)
{
return false;
}
You need to install the MySql NET Connector that provides the appropriate bits to connect to MySQL database.
After installing the provider you need to add a reference to MySql.Data.Dll and add the appropriate using statement to your code
using MySql.Data.MySqlClient;
You also need to change your connection string which could be found in here.
Connection code should look something close to this:
private void Login() // login method
{
string connectString = #"uid=<UserID>;password=<Password>;
server=<IPorDomainNameOfDatabase>;
database=<DatabaseNameOnServer>;";;
using(MySqlConnection cnn = new MySqlConnection(connectString))
{
try
{
cnn.Open();
}
catch (Exception e)
{
.....
}
}
}
Full code could look something like this (command should be edited according to data you want to retrieve):
MySqlConnection connect = new MySqlConnection(connectString);
MySqlCommand command = connect.CreateCommand();
command.CommandText = "Select <VALUE> from <TABLE> order by <ID> desc limit <0,1>;";
//Command to get query needed value from DataBase
connect.Open();
MySqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
var result = reader.GetString(0);
}
Note: I strongly suggest you to put connect.Open(); into TryCatch statment, since there are many things that can do wrong and your program will crash.

C# Asp.net can't connect to phpmyadmin

I am building an appliciation that connects with a database. Now the problem is that i get an error when i try to actually connect to the database. *note, I know its not save, its for testing purposes only.
Also, when i go to the url given in string server = "http://185.13.226.246:2222/CMD_DB/"; directly it will give me an error as in the picture below. But if I go to that URL indirectly (so via navigating) its fine.
It might be a very small problem but I can't find why it does not work.
edit: in the picture below there should be a list of available databases.
public class DataConnection
{
private static SqlConnection conn;
SqlCommand cmd = new SqlCommand();
public DataConnection() { }
public static SqlConnection Connection
{
get { return conn; }
}
public void ReadyConnection()
{
string server = "http://185.13.226.246:2222/CMD_DB/";
string database = "nickbbl114_atop";
string uid = "bbl114";
string password = "password010101";
string port = "2222";
string connectionString;
connectionString = "SERVER=" + server + ";" + "DATABASE=" +
database + ";" + "UID=" + uid + ";" + "PWD=" + password + ";";
conn = new SqlConnection(connectionString);
try
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
}
catch (Exception ex)
{
throw ex;
}
}
public string Login(string email, string password)
{
string naam;
cmd.CommandText = "Select Voornaam From persoon where email = '" + email + "' and password = '" + password + "'";
cmd.CommandType = CommandType.Text;
cmd.Connection = conn;
ReadyConnection();
naam = cmd.ExecuteScalar().ToString();
return naam;
}
}
you can create same database for any type of application either it's in JAVA or Dotnet or PHP.It doesn't matter.
First try to create a service layer in asp.net for Database CRUD operations. 1) EmployeeService - API service. 1.Insert a new record in the table. 2.Delete the record. 3.Update the record.
Sample to create service layer using WCF service - http://www.codeproject.com/Articles/254714/Implement-CRUD-operations-using-RESTful-WCF-Servic
The above layer can be used for both asp.net and PHP.
2)Asp.Net application - Call the above service using Jquery from asp.net application
3)PHP application - Call the above service using jquery from asp.net application

Close MySQL Connection outside Function

I currently have a little app sends a lot of different MySQL Queries to the server. My idea was to wrap the connection, the query and the read to a function with only the actual query as a parameter.
Here is what I got:
public static MySqlDataReader mySqlRead(string cmdText)
{
string connString = "server=" + ORVars.sqlServerAddr + ";port=" + ORVars.sqlServerPort + ";uid=" + ORVars.sqlServerUID + ";pwd=" + ORVars.sqlServerPass + ";database=" + ORVars.sqlServerDB + ";";
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();
command.CommandText = cmdText;
try
{
conn.Open();
MySqlDataReader reader = command.ExecuteReader();
return reader;
}
catch (MySqlException)
{
throw;
}
}
I connect and send the query here:
private void btnLogin_Click(object sender, EventArgs e)
{
string username = txtLogin.Text;
string password = ORFunc.GetMD5Hash(txtPassword.Text);
MySqlDataReader orRead = ORFunc.mySqlRead("SELECT * FROM orUsers WHERE username = '" + username + "' AND pass = '" + password + "'");
while (orRead.Read())
{
MessageBox.Show(orRead["id"].ToString());
}
}
Works like a charm... BUT, as you can see above, the connection is never closed. When I add the conn.Close() behind the .ExecuteReader() the reader is empty and everything after return is of course useless.
Maybe it's a stupid question but I'm rather new to C# so please be generous, any hint is appreciated.
cheers,
PrimuS
I had a similar problem in JAVA recently, but I think the same will work for you. Essentially, you can create a class that represents a "SqlCall" object (or something). The class would have accessible members including the connection and the results. The ctor for the class would take in your query text.
Then, all you would have to do is create a new instance of that class, run the query in a method in that class (which would set and/or return the results), GET the results, and then when you are done, call close() on your class (which would then have to be coded such that it closes the connection held internally).
Technically, a better way to do this is to EXTEND the connection class itself, but as you are new to C#, I will not go into the details of doing so.
As I was writing the code below, I realized I may have not actually answered your question. But there's no point in backing out now, so here's what I have:
public class SqlCall {
private static connString = "server=" + ORVars.sqlServerAddr + ";port=" + ORVars.sqlServerPort + ";uid=" + ORVars.sqlServerUID + ";pwd=" + ORVars.sqlServerPass + ";database=" + ORVars.sqlServerDB + ";";
private MySqlConnection conn;
private MySqlCommand command;
private MySqlDataReader reader;
public SqlCall(String query) {
conn = new MySqlConnection(connString);
command = conn.CreateCommand();
command.CommandText = query;
}
public MySqlDataReader execute() throws Exception {
conn.Open();
reader = command.ExecuteReader();
return reader;
}
public void close() {
reader.close();
conn.close();
}
}
Your login code would be:
private void btnLogin_Click(object sender, EventArgs e) {
string username = txtLogin.Text;
string password = ORFunc.GetMD5Hash(txtPassword.Text);
SqlCall sqlcall = new SqlCall("SELECT * FROM orUsers WHERE username = '" + username + "' AND pass = '" + password + "'");
try {
MySqlDataReader orRead = sqlcall.execute();
while (orRead.Read())
{
MessageBox.Show(orRead["id"].ToString());
}
sqlcall.close();
} catch (Exception ex) {
// dostuff
}
}
The point is, unless you copy the data into a new datatable at the very beginning, you'll have to keep the connection open.
On a separate note, YOUR CODE IS PRONE TO SQL INJECTION. Don't know what that is? An example: if I said my username was ';DROP TABLE orUsers;--, then your entire user database would be gone. Look into stored procedures if you want a (very healthy) way around this.
You have difficulties because your idea works against the pattern expected by programs that connects to a database in NET Framework.
Usually, in this pattern you have a method that
INITIALIZE/OPEN/USE/CLOSE/DESTROY
the ADO.NET objects connected to the work required to extract or update data
Also your code has a serious problem called Sql Injection (see this famous explanation) because when you concatenate strings to form your command text you have no defense against a malicious user that try to attack your database
private void btnLogin_Click(object sender, EventArgs e)
{
string username = txtLogin.Text;
string password = ORFunc.GetMD5Hash(txtPassword.Text);
MySqlParameter p1 = new MySqlParameter("#uname", username);
MySqlParameter p2 = new MySqlParameter("#pass", pass);
string cmdText = "SELECT * FROM orUsers WHERE username = #uname AND pass = #pass"
DataTable dt = ORFunc.GetTable(cmdText, p1, p2);
foreach(DataRow r in dt.Rows)
{
Console.WriteLine(r["ID"].ToString());
}
}
public static DataTable GetTable(string cmdText, params MySqlParameter[] prms)
{
string connString = "server=" + ORVars.sqlServerAddr + ";port=" + ORVars.sqlServerPort + ";uid=" + ORVars.sqlServerUID + ";pwd=" + ORVars.sqlServerPass + ";database=" + ORVars.sqlServerDB + ";";
// This is the INITIALIZE part
using(MySqlConnection conn = new MySqlConnection(connString))
using(MySqlCommand command = new MySqlCommand(cmdText, conn))
{
// OPEN
conn.Open();
DataTable dt = new DataTable();
command.Parameters.AddRange(prms);
// USE
MySqlDataReader reader = command.ExecuteReader();
dt.Load(reader);
return dt;
} // The closing brace of the using statement is the CLOSE/DESTROY part of the pattern
}
Of course this is a generic example and in my real work I don't use very often these generic methods and prefer to write specialized data access code that return the base object needed to the upper layer of code

Categories