使用多个表C#登录

时间:2015-04-20 18:08:33

标签: c# asp.net sql-server

我试图弄清楚如何使用3个表中的数据进行身份验证,然后根据使用的表重定向到不同的页面。我有第一个工作(即使用1个表)问题是当我尝试使用2/3表时。

(我知道SQL注入等我刚刚让页面变得非常简单,试着让它首先工作:))

任何帮助都会因为它让我疯狂而非常适合

继承人正在努力

{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void _login_Click(object sender, EventArgs e)
{
    SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Testconnection"].ConnectionString);
    conn.Open();
    string Checkuser = "Select count(*) from dbo.loginuser where username='" + Textusername.Text + "'";
    SqlCommand com = new SqlCommand(Checkuser, conn);
    int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
    conn.Close();
    if (temp == 1)
    {
        conn.Open();
        string checkPasswordQuery = "select password from dbo.loginuser where username='" + Textusername.Text + "'";
        SqlCommand passComm = new SqlCommand(checkPasswordQuery, conn);
        string password = passComm.ExecuteScalar().ToString().Replace(" ", "");
        if (password == textpassword.Text)
        {
            Session["New"] = Textusername.Text;
            Response.Redirect("Reporthome.aspx");
        }

    }
    else
    {
        conn.Open();
        string Checkuser1 = "Select count(*) from dbo.employee where idno='" + Textusername.Text + "'";
        SqlCommand com1 = new SqlCommand(Checkuser1, conn);
        int temp1 = Convert.ToInt32(com.ExecuteScalar().ToString());
        conn.Close();
        if (temp1 == 1)
        {
            conn.Open();
            string checkPasswordQuery1 = "select epass from dbo.employee where idno='" + Textusername.Text + "'";
            SqlCommand passComm1 = new SqlCommand(checkPasswordQuery1, conn);
            string epass = passComm1.ExecuteScalar().ToString().Replace(" ", "");
            if (epass == textpassword.Text)
            {
                Session["New"] = Textusername.Text;
                Response.Redirect("Engineerhome.aspx");
            }
            else
            {
                Response.Write("password is incorrect");
            }
        }
    }
}

}

2 个答案:

答案 0 :(得分:0)

为什么不尝试使用存储过程并让数据库处理它。如果这三个表具有相同的列或字段,则为所有三个表提供UNION ALL,并将您的凭据传递给存储过程。

处理选择中的整个三个表。还要确保一旦到达那里为您的密码加盐并相应加密并保存产品。

尝试类似......

public class PasswordHash{

public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";

// The following constants may be changed without breaking existing hashes.
public static final int SALT_BYTE_SIZE = 24;
public static final int HASH_BYTE_SIZE = 24;
public static final int PBKDF2_ITERATIONS = 1000;

public static final int ITERATION_INDEX = 0;
public static final int SALT_INDEX = 1;
public static final int PBKDF2_INDEX = 2;

/**
 * Returns a salted PBKDF2 hash of the password.
 *
 * @param   password    the password to hash
 * @return              a salted PBKDF2 hash of the password
 */
public static String createHash(String password)
    throws NoSuchAlgorithmException, InvalidKeySpecException
{
    return createHash(password.toCharArray());
}

/**
 * Returns a salted PBKDF2 hash of the password.
 *
 * @param   password    the password to hash
 * @return              a salted PBKDF2 hash of the password
 */
public static String createHash(char[] password)
    throws NoSuchAlgorithmException, InvalidKeySpecException
{
    // Generate a random salt
    SecureRandom random = new SecureRandom();
    byte[] salt = new byte[SALT_BYTE_SIZE];
    random.nextBytes(salt);

    // Hash the password
    byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
    // format iterations:salt:hash
    return PBKDF2_ITERATIONS + ":" + toHex(salt) + ":" +  toHex(hash);
}

/**
 * Validates a password using a hash.
 *
 * @param   password        the password to check
 * @param   correctHash     the hash of the valid password
 * @return                  true if the password is correct, false if not
 */
public static boolean validatePassword(String password, String correctHash)
    throws NoSuchAlgorithmException, InvalidKeySpecException
{
    return validatePassword(password.toCharArray(), correctHash);
}

/**
 * Validates a password using a hash.
 *
 * @param   password        the password to check
 * @param   correctHash     the hash of the valid password
 * @return                  true if the password is correct, false if not
 */
public static boolean validatePassword(char[] password, String correctHash)
    throws NoSuchAlgorithmException, InvalidKeySpecException
{
    // Decode the hash into its parameters
    String[] params = correctHash.split(":");
    int iterations = Integer.parseInt(params[ITERATION_INDEX]);
    byte[] salt = fromHex(params[SALT_INDEX]);
    byte[] hash = fromHex(params[PBKDF2_INDEX]);
    // Compute the hash of the provided password, using the same salt, 
    // iteration count, and hash length
    byte[] testHash = pbkdf2(password, salt, iterations, hash.length);
    // Compare the hashes in constant time. The password is correct if
    // both hashes match.
    return slowEquals(hash, testHash);
}

/**
 * Compares two byte arrays in length-constant time. This comparison method
 * is used so that password hashes cannot be extracted from an on-line 
 * system using a timing attack and then attacked off-line.
 * 
 * @param   a       the first byte array
 * @param   b       the second byte array 
 * @return          true if both byte arrays are the same, false if not
 */
private static boolean slowEquals(byte[] a, byte[] b)
{
    int diff = a.length ^ b.length;
    for(int i = 0; i < a.length && i < b.length; i++)
        diff |= a[i] ^ b[i];
    return diff == 0;
}

/**
 *  Computes the PBKDF2 hash of a password.
 *
 * @param   password    the password to hash.
 * @param   salt        the salt
 * @param   iterations  the iteration count (slowness factor)
 * @param   bytes       the length of the hash to compute in bytes
 * @return              the PBDKF2 hash of the password
 */
private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes)
    throws NoSuchAlgorithmException, InvalidKeySpecException
{
    PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
    SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
    return skf.generateSecret(spec).getEncoded();
}

/**
 * Converts a string of hexadecimal characters into a byte array.
 *
 * @param   hex         the hex string
 * @return              the hex string decoded into a byte array
 */
private static byte[] fromHex(String hex)
{
    byte[] binary = new byte[hex.length() / 2];
    for(int i = 0; i < binary.length; i++)
    {
        binary[i] = (byte)Integer.parseInt(hex.substring(2*i, 2*i+2), 16);
    }
    return binary;
}

/**
 * Converts a byte array into a hexadecimal string.
 *
 * @param   array       the byte array to convert
 * @return              a length*2 character string encoding the byte array
 */
private static String toHex(byte[] array)
{
    BigInteger bi = new BigInteger(1, array);
    String hex = bi.toString(16);
    int paddingLength = (array.length * 2) - hex.length();
    if(paddingLength > 0)
        return String.format("%0" + paddingLength + "d", 0) + hex;
    else
        return hex;
}

/**
 * Tests the basic functionality of the PasswordHash class
 *
 * @param   args        ignored
 */
public static void main(String[] args)
{
    try
    {
        // Print out 10 hashes
        for(int i = 0; i < 10; i++)
            System.out.println(PasswordHash.createHash("p\r\nassw0Rd!"));

        // Test password validation
        boolean failure = false;
        System.out.println("Running tests...");
        for(int i = 0; i < 100; i++)
        {
            String password = ""+i;
            String hash = createHash(password);
            String secondHash = createHash(password);
            if(hash.equals(secondHash)) {
                System.out.println("FAILURE: TWO HASHES ARE EQUAL!");
                failure = true;
            }
            String wrongPassword = ""+(i+1);
            if(validatePassword(wrongPassword, hash)) {
                System.out.println("FAILURE: WRONG PASSWORD ACCEPTED!");
                failure = true;
            }
            if(!validatePassword(password, hash)) {
                System.out.println("FAILURE: GOOD PASSWORD NOT ACCEPTED!");
                failure = true;
            }
        }
        if(failure)
            System.out.println("TESTS FAILED!");
        else
            System.out.println("TESTS PASSED!");
    }
    catch(Exception ex)
    {
        System.out.println("ERROR: " + ex);
    }
}

}

答案 1 :(得分:0)

由于您的两个编码元素非常相似,您还可以创建一个对两个元素都通用的单独例程,例如此版本的EmpPassword

private string EmpPassword(string sqlText, System.Data.SqlClient.SqlConnection openConnection)
{
    object obj = null;
    using (var cmd = new System.Data.SqlClient.SqlCommand(sqlText, openConnection))
    {
        using (var r = cmd.ExecuteReader())
        {
            if (r.Read())
            {
                obj = r.GetValue(0);
            }
        }
    }
    if ((obj != null) && (obj != DBNull.Value))
    {
        return obj.ToString().Replace(" ", "");
    }
    return null;
}

您的_login_Click事件可以使用相同的数据库连接对象调用您的每个数据库,具体取决于结果:

protected void _login_Click(object sender, EventArgs e)
{
    using (var con = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings["Testconnection"].ConnectionString))
    {
        Session["New"] = null;
        try
        {
            con.Open();
            var sqlText = String.Format("SELECT password FROM dbo.loginuser WHERE username='{0}';", Textusername.Text);
            var sqlResult = EmpPassword(sqlText, con);
            if (sqlResult == textpassword.Text)
            {
                Session["New"] = Textusername.Text;
                Response.Redirect("Reporthome.aspx");
            }
            else
            {
                sqlText = String.Format("Select epass from dbo.employee where idno='{0}';", Textusername.Text);
                sqlResult = EmpPassword(sqlText, con);
                if (sqlResult == textpassword.Text)
                {
                    Session["New"] = Textusername.Text;
                    Response.Redirect("Engineerhome.aspx");
                }
                else
                {
                    Response.Write("password is incorrect");
                }
            }
        }
        finally
        {
            con.Close();
        }
    }
}

注意我在两者上都跳过了SELECT Count(*)选项。如果用户存在于表中,则将返回该用户。

当然,如果您的架构允许具有相同用户ID的多个实例,那么这将无效。