How to match username and password after querying - java

How could I check if the username and password (taken as input in a login page) match? All of the information is stored in a Derby DB. I just need to know if the correct password is entered for a username that is given.
Here is my code:
public void checkIdPw(String userName, String passWord) {
try {
stmt = conn.createStatement();
String checkPwforIdSQL = "SELECT PASSWORD FROM " + studentsTable + " WHERE USERNAME = '" + userName + "'";
stmt.executeQuery(checkPwforIdSQL);
stmt.close();
} catch(SQLException sqlExcept) {
sqlExcept.printStackTrace();
}
}

It is poor security to store passwords unencrypted and encrypting them with something like Bcrypt would be much better.
Something like the following should work for what you need. Using a PreparedStatement is crucial and simple string concatenation should never be done as it allows for SQL injection attacks.
PreparedStatement stmt = conn.prepareStatement(
"SELECT USERNAME FROM studentsTable WHERE USERNAME = ? AND PASSWORD = ?");
stmt.setString(1, username);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
// valid credentials
} else {
// invalid credentials
}
rs.close();
stmt.close();
Depending on the nature of the site another good practice is to display the same generic message to the user on failed regardless of whether it was the username (or email address) or password that was incorrect. An example message is "Invalid username or password." The benefit to this is that it helps prevent username harvesting as the attacker would not be able to tell from the error message that the username is valid. For some sites this matters more than others and a site where the usernames are already public would not benefit as much as other harvesting methods are available.

Related

Java Login Form somehow skips if-else statement

I am trying to create a Login and Register form using Java and SQL Workbench. The Register form works properly as the Username and Password are added to the SQL Database. As for the Login form, everything looks fine. But, when it is executed, it skips the If Statement and goes straight to the Else Statement. The Username and Password are correct as I checked the SQL Database table. The output is a SqlSyntaxErrorException. Therefore, I think my syntax is wrong. Any help would be highly appreciated!
This is the code below:
if (e.getSource() == LOG_IN_BUTTON)
{
String userName = USER_NAME_TEXTFIELD.getText();
String password = PASSWORD_TEXTFIELD.getText();
try {
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/airline_connect",
"root", "Yasser1595");
String sql = "Select user_name, password from account where user_name=? and password=?";
st = connection.prepareStatement(sql);
st.setString(1, userName);
st.setString(2, password);
ResultSet rs = st.executeQuery(sql);
if (rs.next()) {
frame.dispose();
new MainGame();
JOptionPane.showMessageDialog(LOG_IN_BUTTON, "You have successfully logged in");
} else {
JOptionPane.showMessageDialog(LOG_IN_BUTTON, "Wrong Username & Password");
}
} catch (Exception exc) {
exc.printStackTrace();
}
}
Try the following,
ResultSet rs = st.executeQuery();
Don't pass the sql string to executeQuery. When you pass the sql string to executeQuery it considers it as plain text instead of prepared statement
You did not use PreparedStatement.executeQuery() but the parent's Statement.executeQuery(sql) which is a known pitfall. Also it is worth using try-with-resources with local variables. Not closing things can cause resource leaks.
String sql = "select user_name, password from account where user_name=? and password=?";
try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/airline_connect",
"root", "Yasser1595");
PreparedStatement st = connection.prepareStatement(sql)) {
st.setString(1, userName);
st.setString(2, password);
try (ResultSet rs = st.executeQuery()) { // No sql parameter.
if (rs.next()) {
frame.dispose();
new MainGame();
JOptionPane.showMessageDialog(LOG_IN_BUTTON, "You have successfully logged in");
return;
}
JOptionPane.showMessageDialog(LOG_IN_BUTTON, "Wrong Username & Password");
}
} catch (SQLException exc) {
exc.printStackTrace();
}
It still did not work
PASSWORD also is a function, but as no syntax errors happend, that probably is no problem. You might try "password" (= column name).
The column might store not the password - which is a security risk, should
the database be stolen in the future. It might store some hash of the password.
So:
String sql = "SELECT user_name, \"password\" "
+ "FROM account "
+ "WHERE user_name=? AND \"password\"=PASSWORD(?)";
First check how passwords (or their hashes) are stored.
It might also be the case that the password handling is done at the java side, for instance by taking the MD5 of the password and storing that.
Should all work, consider an other securite measure: if the password field is a JPasswordField one should ideally not work with a String, but a char[] that can be wiped out after usage (Arrays.setAll(pwdArray, ' ');). A String could reside long in memory, which might be a security risk.

verify BCrypt password stored in database

I working on a log in system in Java and I am using PostgreSQL. I have a registration form that saves the user information to the database. It also hashes the password before storing. I am now trying to verify the password that the user enters against the hashed password in the database.
try {
//connects to the database
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/cc", "pi", "server");
//prepares SELECT statement
PreparedStatement statement = conn.prepareStatement("SELECT username, user_pass FROM users WHERE username = '" + username +"';");
ResultSet result = statement.executeQuery();
String upass = new String(password.getPassword());
String user = "";
String pass = "";
while(result.next()){
user = result.getString("username");
pass = result.getString("user_pass");
}
if(username.equals(user) && BCrypt.checkpw(upass, pass)){
frame.dispose();
new CommunityCooks();
}
else{
JOptionPane.showMessageDialog(null, "incorrect credentials");
}
}
catch(SQLException f){
f.printStackTrace();
}
This is the section that I am trying to verify the password matches. The "password" variable is a JPasswordField and the "username" variable is a JTextField. The stored credentials are 'tester' for the username and password and I am able to verify them as local variables and fields. I think the issue I am having is with the translation of the JTextField and the JPasswordField. What I am looking for help on is getting the username and password that the user enters to verify against the stored credentials after the password is hashed from the registration form. The issue I am having is that I can run the application and the login frame opens. I enter the test credentials and it is not matching. I’m getting my incorrect credentials message. I am unclear about the syntax for comparing the stored username (not hashed) and the stored password (hashed) against the user input credentials in the JTextField and the JPasswordField. I thought what I had was correct but it appears to not be right. The testing I have done for it works to read the database and verify but it is not working when I implement it in my program. The only difference in the two is the use of the fields where the test did not use them. My test is below:
public class Main {
public static void main(String[] args) {
String firstName = "tester";
String lastName = "tester";
String email = "tester";
String username = "tester";
String password = "tester";
try {
//connects to the database
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/cc", "pi", "server");
//inserts values into table
PreparedStatement statement = conn.prepareStatement("insert into users values(?,?,?,?,?)");
statement.setString(1, firstName);
statement.setString(2, lastName);
statement.setString(3, email);
statement.setString(4, username);
statement.setString(5, BCrypt.hashpw(password, BCrypt.gensalt()));
PreparedStatement st = conn.prepareStatement("SELECT username, user_pass FROM users WHERE username = '" + username + "';");
ResultSet result = st.executeQuery();
String u = null;
String p = null;
while (result.next()) {
u = result.getString("username");
p = result.getString("user_pass");
}
System.out.println(u);
System.out.println(p);
System.out.println(BCrypt.checkpw(password, p));
} catch(SQLException f){
f.printStackTrace();
}
}
}
The test output works and shows the username and the hashed password and stating that it is "true" to being verified.
Any guidance will be greatly appreciated. This is my first time using a hash system.

50894 ERROR reading: Incorrect syntax near the keyword 'user' when tries to select query to compare the username and password

public void login(String name,String password) throws SQLException{
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException ex) {
Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ex);
}
java.sql.Connection conn = DriverManager.getConnection("jdbc:sqlserver://127.0.0.1;"+"user=looi963;password=1234;database=user");
PreparedStatement state=conn.prepareStatement("Select username,password from user where username=? and password = ?");
state.setString(1,name);
state.setString(2, password );
int count = state.executeUpdate();
if(count>0){
System.out.println("Successful login");
}
}
Protect the identifier as USER is a reserved keyword and it cannot be used "bare". Consider the following which uses the []-quotes (""-quotes would also work);
Select username,password from [user] where username = ? and password = ?
This error is fairly common (for different reserved words) - make sure to consult the manual. Ideally, I would name the tables and columns such that they are not any of the reserved keywords.
Also, change executeUpdate() to executeQuery() because it's a SELECT operation.
It may also be prudent to switch to a user table that does not store the plain-text passwords.. the problem with plain-text passwords is two-fold;
an unauthorized read on the table instantly compromises all accounts, and;
people often reuse passwords which can make their other accounts (eg. email, bank) vulnerable.
As you are using a select query replace this
state.executeUpdate(); with ResultSet rs = state.executeQuery()
then check if records exists with the specified username and password like this
if (!rs.next() ) {
System.out.println("Not valid username and password");
} else {
do {
System.out.println(rs.getString(1)+" "+
rs.getString(2);
} while (resultSet.next());
}

compare records and login?

I have a table:
create table User1(Username varchar2(20) ,
First_Name varchar2(20) ,
Last_Name varchar2(20) ,
Password varchar2(20) ,
Date_Of_Birth Date )
Also a login page with 2 fields username and password , a button "login"
Now suppose the Admin has added 4 users i.e 4 records in User1 table with their details.
saywith firstnames-U1,U2,U3,U4 each having a Username and a password.
Now suppose User1 wants to login ,he'll have to provide his own username and password to continue..
Now help me with the JDBC code for successful login::
if(e.getSource()==submit)
{
Connection con=null;
ResultSet rs=null;
try
{
Class.forName("oracle.jdbc.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1522:xe", "hr", "hr");
PreparedStatement st=con.prepareStatement("select count(1) from User1 where Username = ? and Password = ? ");
st.setString(1, text1.getText());
st.setString(2, p1.getText());
rs= st.executeQuery();
//String t1=text1.getText();
//String t2= p1.getText();
if (rs.getInt(1) == 1)
{
new Rec_options();
}
}
catch(SQLException ee)
{
System.out.println(ee);
}
finally
{
rs.close();
con.close();
}
}
Now i'm confused what should i do inside the loop.I want is that the username and password entered in the respective fields by the user should be compared with the "Username" and "Password" columns of the table User1 ,and when any record is found with the same username and password as the one entered by the User ,login should be successful..
Please help!
Thanks
Once if you get resultset you can get data using getString() methode as follows.
if(rs.getString(1).equals(text1.getText() && rs.getString(4).equals(p1.getText())
{
//login success
}
Hope this link will help you.
Let's say you have 1 million users. Would you find it effective to get all the users from the database, and compare their username and password with the ones entered?
A database is used to store data, and to be able to query the data. You should search for a user which has the entered usename, and the entered password. If you find one, then the user is authenticated. If you don't find any, then either the username or the password is wrong.
Read the JDBC tutorial about prepared statements. Your query should look like
select <what_you_need> from user where username = ? and password = ?
Also, if this is more than a toy application that is not meant to go to production, you should not store passwords in clear text in the database. Passwords must be cryptographically salted and hashed, preferrably with a slow algorithm.
Count the records that match your username and password values:
PreparedStatement st=con.prepareStatement("select count(1) from User1 where username = ? and password = ?");
st.setParameter(1, text1.getText());
st.setParameter(2, p1.getText());
ResultSet rs= st.executeQuery();
rs.next();
if (rs.getInt(1) == 1) {
// login succesfull
}
rs.close();
Note: this is a very simplistic approach. You might want to add exception handling (e.g. make sure your JDBC resources are always closed properly. Also consider storing some hashes of passwords, rather the passwords in plain text in the database.
JTextField text1;//username
JPasswordField p1;//password
try{
Class.forName("oracle.jdbc.OracleDriver");
Connection con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1522:xe", "hr", "hr");
PreparedStatement st=con.prepareStatement("SELECT * from User1 WHERE Username = ? AND Password = ? ");
st.setParameter(1, text1.getText());
st.setParameter(2, p1.getText());
ResultSet rs= st.executeQuery();
if(rs.next())
{
//Login successfull.
}
}
catch (SQLException s){
System.out.println("SQL statement is not executed!");
}
finally{
rs.close();
con.close();
}

I'm trying to Validate username and password

I am trying to ensure that when a user enters username & password, authentication is done by checking if input matches some row in the user table. Here is the code so far: It doesn't respond when the login button is click. Please suggest how I can set it right. Thanks
private void dbConnection()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/maths_tutor", "root", "jesus");
Statement stmt = conn.createStatement();
String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND password = '"+this.txtPass+"'";
ResultSet rs = stmt.executeQuery(CHECK_USER);
while(rs.next())
{
String user = txtUser.getText();
String pass = txtPass.getText();
if(user.equals(rs.getString("username")))
{
if(pass.equals(rs.getString("password")))
{
this.dispose();
new AboutTo().setVisible(true);
}
else JOptionPane.showMessageDialog(null, "Invalid Password");
}
else JOptionPane.showMessageDialog(null, "Invalid Username or Password");
}
stmt.close();
rs.close();
conn.close();
}
catch(SQLException | ClassNotFoundException er)
{
JOptionPane.showMessageDialog(null, "Exception:\n" + er.toString());
}
}
String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND password = '"+this.txtPass+"'";
you have passed username & password in sql query so it go in while block only if username And password will match ...
you supposed to make sql querylike this
String CHECK_USER = "SELECT * FROM records";
or you can use if block like this
if(rs.next()
{
//login successfull code
}
else
{
//login fail
}
Basically, the logic is wrong.
What you are doing is approximately this.
Get a username and a password from the user.
Ask the database for all records for which the user name is matches the supplied username and the password matches the supplied password.
For each such record:
Test if the user name matches, and open a dialog if it doesn't match. That won't happen ... because you only selected records with that user name.
Test if the password matches, and open a dialog if it doesn't match. That won't happen ... because you only selected records with that password.
What you really ought to be doing is:
Get a username and a password from the user.
Select the records that match the user name and password.
Print a message if the number of records that you matched is zero.
I should also point out some other things:
Popping up a dialog box to tell the user his user name / password are wrong is beside the point. What you really need to do is tell something else in your server that the login failed.
When the user gets just the username or just the password incorrect, you should not offer him any clues that one was correct. Doing that makes it easier for "the bad guy" to work out the correct combination.
Storing passwords in clear in a database is Bad Practice. Best practice is to store seeded hashes of the passwords ... and use a cryptographically strong hashing function.
You forgot to call getText() on txtUser and txtPass.
This is how you could fix your query:
String CHECK_USER = "SELECT * FROM records WHERE username = '" + this.txtUser.getText() + "' AND password = '" + this.txtPass.getText() + "'";
You should note that concatenation of raw input text to queries will open vulnerability to SQL injection. You should use PreparedStatement instead so that the input text is properly escaped.
The following is a way to implement this properly, however lacks the following things that should be of concern to you:
You are storing passwords in clear text. You should use a hashing function such as SHA-1.
Every authentication will result in a new connection to the database. You should probably use a proper connection pool.
.
private boolean authenticate() throws SQLException {
String dbUrl = "jdbc:mysql://localhost:3306/maths_tutor";
// This query will simply count the matching rows, instead of actually selecting
// them. This will result in less bandwidth between your application and the server
String query = "SELECT count(*) AS num_records FROM records WHERE username = ? AND password = ?";
// Obtaining the username and password beforehand could perhaps make it more clear
// and prevent errors instead of pulling the data every time you need it
String username = txtUser.getText();
String password = txtPass.getText();
// The try-with-resources block will make sure the resources are closed once we are done with
// them. More information available at
// http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
try (
// Open database connection
Connection conn = DriverManager.getConnection(dbUrl, "root", "jesus");
// Prepare the statement
PreparedStatement stmt = conn.prepareStatement(query)
) {
// Set the username and password for the SQL statement
stmt.setString(1, username);
stmt.setString(2, password);
// Execute the query in a try block, to ensure that the resources
// will be released
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
// If we got 1 or more matches, this means we successfully
// authenticated. Otherwise, we failed authentication.
return rs.getInt("num_records") > 0;
}
}
}
// Failed authentication.
return false;
}
// Rename this to something meaningful according to your application
private void doAuthentication() {
try {
if (authenticate()) {
// Do successful authentication handling
this.dispose();
new AboutTo().setVisible(true);
} else {
// Do failed authentication handling
JOptionPane.showMessageDialog(null, "Invalid Username or Password");
}
} catch(SQLException er) {
// Do error handling
JOptionPane.showMessageDialog(null, "Exception:\n" + er.toString());
}
}
The possible error would be near this line
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/maths_tutor", "root", "jesus");
first make sure you have set the classpath and added the mysql driver to the project
second I would the following instead of the above, in fact why do you make things to much complex?!
java.sql.Driver _dr=new com.mysql.jdbc.Driver();
java.util.Properties _pr=new java.util.Properties();
_pr.setProperty("user","root");
_pr.setProperty("password","jesus");
Connection conn = _dr.connect("jdbc:mysql://localhost:3306/maths_tutor", _pr);
and the last thing is beware about using this like of code
String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND password = '"+this.txtPass+"'";
so here the system is ready for injection.
so the good way would be like this, using parameters.
String CHECK_USER = "SELECT * FROM records WHERE username = ? AND password = ?";//this will avoid sql injection
java.sql.PreparedStatement _st=conn.prepareStatement(CHECK_USER);
_st.setString(1, this.txtUser);
_st.setString(1, this.txtPass);
EDIT :by the way, there is no need to iterate over result set! simple just call the next() method, if it returns true, so it means user has entered correct user/pass, else otherwise.
ResultSet rs = stmt.executeQuery(CHECK_USER);
if(rs.next()){/*user exist*/
this.dispose();
new AboutTo().setVisible(true); }
else{
JOptionPane.showMessageDialog(null, "Invalid Username or Password");
}
string query = "SELECT count(*) FROM [dbo].[login1] WHERE username='" + username.Text + "' and password='" + password.Text + "'";
SqlDataAdapter sda = new SqlDataAdapter(query, con);
DataTable dt = new DataTable();
sda.Fill(dt);
if (dt.Rows[0][0].ToString() == "1")
{MessageBox.Show("YEAH");}

Categories