开发者

Best way to authenticate a user with MySQL (Open to other suggestions)?

I´m creating a web based login system and for that I´m using MySQL as my backend and, JSPS and Servlets for functionality, also using a library called jasypt 1.8 to encrypt passwords to later store them on MySQL.

My question is: Is there anything wrong with the following code (Security related, best practices, etc...):

 protected boolean verifyUser(String user, String pass) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {

    StrongPasswordEncryptor passwordEncryptor = new StrongPasswordEncryptor();

    Connection conn = null;
    String userName = "****";
    String password = "****";
    String url = "jdbc:mysql://localhost:3306/DB";
    ResultSet rs = null;
    try {
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        conn = DriverManager.getConnection(url, userName, password);
        System.out.println("Database connection established");

        PreparedStatement stmt = null;

        stmt = conn.prepareStatement("SELECT * FROM DB.LOGINS WHERE USER = ?");
        stmt.setString(1, user);
        rs = stmt.executeQuery();
        if(!rs.next()){
            return false;                
        }

        if(passwordEncryptor.checkPassword(pass, rs.getString("Password"))){
            return true;
        }
        conn.close();
    } catch (Exception e) {

    }
    return false;
}

I don´t know if it is correct to get the user out of the database and then comparing it with the password that has been provided (i开发者_开发问答e. I would think that the best way would be to get the information out of the database using the username AND the password, not just the former). I´m unfortunately unable to do this because I can´t generate the key because there is no method in the library able to do it (And I have not been able to find the algorithm in the documentation to generate the key).

I´m doing this because the library I´m using has an inbuilt random salt generator that stores itself within the string that is created after the encryption (Using sha-256 for this if it matters...) and the method checkPassword() is the only thing that is able to generate a key that is exactly the same to the one stored in the database (Which has already gone trough encryption process).

Anyway if you have any experience with creating login systems or know a lot of security best practices I would like you to tell me what your experience is with this kind of problems if you don´t find my solution appropriate.

Thank you for your time.


Jasypt exactly makes it easy for you to do this kind of password check, so the code that checks the password is quite okay.

The main comment I would have is that there are two many things happening in that method.

  • getting a sql connection
  • printing the connection message on the console
  • getting a user
  • check it is not null
  • checking the password with an internal StrongPasswordEncryptor

Meaning everything is pretty much hardcoded in that method

To make this better, I would:

  • use a logging system Log4j
  • separate the configuration of the connection somewhere else (property file ...)
  • eventually use a connection pool (here's one example for MySQL
  • don't have an enpty catch block, throw the exception, or at least log it, so you know what is happening
  • also, in case you want to change your Jasypt options, you should make the password encryption mechanism outside this method.

Anyway, only a few things to make it more modular.

Now in production systems, most people would prefer to use a framework like Apache Shiro so they can easily change the authentication mechanism, and also, configure roles and groups easily.

Voila. Hope this answer sheds a bit oflight.


Considering the username is unique in system, your solution to read user information and compare password hash is OK and it is widely used solution. No security risk is involved, as long as the whole processing is done on server side.

However, if you would like to use such a code in practical application, you should not create connection each time but consider using connection pools such as apache commons dbcp, which additionally simplifies development ;)


also using a library called jasypt 1.8 to encrypt passwords

You MUST NOT encrypt passwords. You should one-way hash them, and compare the hashes. You mustn't provide anything that can be construed legally as a way for someone else to know the user's password. Otherwise you lose legal non-repudiability of transactions, and this is serious enough to put you out of business. You need to take legal advice about this, it is really really serious.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜