-1

I have a little web application on asp.net MVC + PostgreSQL.

I have login page, where people enters their login/password. Right now I only have 1 user - admin. If login and pass are correct, I enter to mainForm.aspx page.

But I need to make a couple of users: user and director. When user logs in, he needs to be redirected to user.aspx page, when director logs in, he needs to be redirected to director.aspx page. All cases need to make login/pass check from PostgreSQL database.

How do I do that?

Here's my Login.aspx.cs code with only 1 user:

namespace User1.WebApp
{
    public partial class Login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            this.UnobtrusiveValidationMode = System.Web.UI.UnobtrusiveValidationMode.None;
        }
        protected void Button_Login_Click(object sender, EventArgs e)
        {
            var connString = "Host=localhost;Username=postgres;Password=123;Database=postgres";
            using (var conn = new NpgsqlConnection(connString))
            {
                conn.Open();
                string checkuser = "select count(*) from Login where name= '" + TextBoxUserName.Text + "' ";
                NpgsqlCommand com = new NpgsqlCommand(checkuser, conn);
                int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
                if (temp == 1)
                {
                    string checkPasswordQuery = "select password from Login where name= '" + TextBoxUserName.Text + "'";
                    NpgsqlCommand passCom = new NpgsqlCommand(checkPasswordQuery, conn);
                    string password = passCom.ExecuteScalar().ToString().Replace(" ", "");
                    if (password == TextBoxPassword.Text)
                    {
                        Session["New"] = TextBoxUserName.Text;
                        Response.Redirect("MainForm.aspx");
                    }
                    else
                    {
                        Response.Write("Password is  NOT correct !");
                    }
                }
                else
                {
                    Response.Write("Username is  NOT correct !");
                }
            }
        }
    }
}
Ralf
  • 16,086
  • 4
  • 44
  • 68
badahboom
  • 49
  • 1
  • 7
  • 1
    I see no attempt at doing anything like this in your example and therefore don't think your question is ok for SO, at least not without editting and further indication that you tried. This is also a VERY broad question,there are many different ways to perfrom what you want... – Laurent S. Aug 08 '18 at 14:43
  • Yeah, i know... I'm very newbie to C# and programming at all... Just started to write my first web application... So i just had no idea how to do this. – badahboom Aug 09 '18 at 03:53
  • @badahboom ASP.NET already has *strong cryptographic* authentication and authorization. You don't need *any* of that code. In fact, this can land you in court and a GDPR fine. This code is wide open to SQL Injection attacks and can reveal all usernames and passwords simply by entering `' OR 1=1;--` as a username or password. – Panagiotis Kanavos Aug 09 '18 at 07:14
  • @badahboom Don't try to create your own authentication and authorization. Use the built-in, [well documented](https://www.asp.net/mvc/overview/security) ASP.NET Identity system. It's covered in all ASP.NET MVC tutorials. Checking roles and permissions is called `authorization`. All you need to check the role is `User.IsInRole(someRole)` to check the user's role or `GetRoles()` to get all roles – Panagiotis Kanavos Aug 09 '18 at 07:16
  • @badahboom how do you think all those password megabreaches in the last couple of years happened? It's not a joke. In fact, ASP.NET *avoided* such issues *precisely* because it already provided strong authentication. – Panagiotis Kanavos Aug 09 '18 at 07:52
  • @Panagiotis Kanavos Thanks for all that information! But this just a test project. In the future I will learn about User.IsInRole method. P.S. Don't want to be under the court :) – badahboom Aug 09 '18 at 07:52
  • @badahboom in fact, hackers scan SO for such vulnerabilities to identify targets, their companies and their clients. Even if cleartext password storage doesn't end in production, the final code may contain other, similar common vulnerabilities – Panagiotis Kanavos Aug 09 '18 at 07:54

2 Answers2

1

You could do this just before

 Response.Redirect("MainForm.aspx");

The way you can do it is to check the type of user and act accordingly.

Few comments regarding the current code:

  • Set the connection string in web.config and read it from there instead of having it hard coded in your code e.g. here.
  • The way you create your SQL statements makes your application vulnerable to SQL injection, one of the most common ways for someone to hack a site. Instead of doing this, prefer parameterized queries.
  • You make two round trips to the database, to check if the user exists and then to get her password. What about if you want to fetch one more information like the user type ? You would make one more round trip. You could eliminate all this to one round trip, provided that you can identify your users based on something unique like the username. Just fetch all the data for a specific username.
  • Let that someone can get access to the Login table of your database. How exposed are your application users ? 100%. All the passwords there are in clear text ! You should avoid this in any way. A naive solution is to hash the password and each time someone try to login to hash the password that the user provides and compare with the hash you have stored. A more professional approach of storing passwords is described at The right way to implement password hashing using PBKDF2 and C#. Look also for similar articles like the mentioned one. Security should be of paramount importance for your applications.
Christos
  • 53,228
  • 8
  • 76
  • 108
-1

Are you able to store an extra field in the database to specify whether a login is Admin, User or Director?

You could use an Enum for this:

enum LoginRole
{
    User = 0,
    Director = 1,
    Admin = 2
}

This Enum could be stored as an integer field in your Login table, called "role" or similar. You could then redirect to the appropriate page depending on this role.

I have updated your code with an example:

var connString = "Host=localhost;Username=postgres;Password=123;Database=postgres";

using (var conn = new NpgsqlConnection(connString))
{
    conn.Open();

    string checkuser = "select password, role from Login where name=@username";

    using (var com = new NpgsqlCommand(checkuser, conn))
    {
        com.Parameters.AddWithValue("@username", TextBoxUserName.Text);

        using (var reader = com.ExecuteReader())
        {
            if (reader.Read())
            {
                string password = reader["password"].ToString();
                LoginRole role = (LoginRole)reader["role"];

                if (password == TextBoxPassword.Text)
                {
                    Session["New"] = TextBoxUserName.Text;
                    switch (role)
                    {
                        case LoginRole.User:
                            Response.Redirect("user.aspx");
                            break;

                        case LoginRole.Admin:
                            Response.Redirect("MainForm.aspx");
                            break;

                        case LoginRole.Director:
                            Response.Redirect("director.aspx");
                            break;
                    }
                }
                else
                    Response.Write("Password is  NOT correct !");
            }
            else
                Response.Write("Username is  NOT correct !");
        }
    }
}

Please note, using parameters in your queries in this case would be preferred, as appending the string from the textbox straight into the SQL query is vulnerable to SQL injection.

You were also making two calls to the database per login - one to check the username and another to check the password. I have addressed this in my above sample to only make one call to the database.

LemonClock
  • 24
  • 3
  • Thank you! That was exactly what i was looking for! "Are you able to store an extra field in the database to specify whether a login is Admin, User or Director?" - Yes, i have two tables - users and roles that connected by foreign key – badahboom Aug 09 '18 at 03:48
  • @badahboom that's actually a *very* bad code that can get you fired or land you in court. ASP.NET already has strong password authentication *and* authorization. Both this answer and the original code are wide open to SQL injection attacks and can reveal *ALL usernames and passwords*. Just enter `' OR 1=1;--` as a username – Panagiotis Kanavos Aug 09 '18 at 07:12
  • [This is a clear explanation](https://www.xkcd.com/327/) why this code is so bad. It's not needed either. A single call to `User.IsInRole("somerole")` can check the role – Panagiotis Kanavos Aug 09 '18 at 07:18