When i try this one, can't access the default file in login. I already checked the the database and tables they are the same. I'm trying to create multiple users but I can't login. What is the proper way of accessing multiple user?
if (Sessions.Current.authenticated != null)
{
if (Sessions.Current.authenticated)
{
Response.Redirect("Admin/Default2.aspx");
}
}
}
protected void login(object sender, EventArgs e)
{
string username = txtUsername.Text.ToString();
string password = txtPassword.Text.ToString();
DataTable dtUser = DBConnector.getTable("SELECT * FROM User WHERE Username = '" + username + "' AND Password = '" + password, false);
if (dtUser.Rows.Count > 0)
{
DataRow dr = dtUser.Rows[0];
Sessions.Current.authenticated = true;
Sessions.Current.lastfirst = dr["Name"].ToString();
Sessions.Current.Usertype = dr["userType"].ToString();
Response.Redirect("Admin/Default2.aspx");
Response.Redirect("web/Default.aspx");
}
}
Ok first of all this code is atrocious. Anybody can use SQL injection to login to your website without using a password or username. Use parameterized queries instead.
Dont make queries in this way
DataTable dtUser = DBConnector.getTable("SELECT * FROM User WHERE Username = '" + username + "' AND Password = '" + password, false);
Now to the problem you are facing. i.e you are not hitting the Default page. This is because of
Response.Redirect("Admin/Default2.aspx");
Once this code is executed the control leaves this page and goes to Page_Load event of Default.aspx2. So doesnt matter what you write after that, its not gonna get executed.
Related
I am trying to redirect my login.htm to index.htm in c#. both files are inside the folder named 'default'. after logging in, if the credential is correct, I want to redirect the login page to index. using the code below, but there is an exception message Attempted to cancel thread.. Is there a way to fix this?? How you can help me. Thanks in advance.
[WebMethod]
public void LogMeIn(string user, string pass) {
try {
using (MySqlConnection dbConn = new MySqlConnection(connectionString())) {
if (dbConn.State == System.Data.ConnectionState.Open) dbConn.Close();
dbConn.Open();
MySqlCommand sqlCmd = new MySqlCommand("SELECT * FROM tbllogin WHERE userName = '" + user + "' AND passWord ='" + pass + "'", dbConn);
int rowCount = (int)sqlCmd.ExecuteScalar();
if (rowCount > 0) {
HttpContext.Current.Response.Redirect("../default/index.htm"); //redirect to new htm page
}
}
}
catch (Exception ex) {
Console.WriteLine("Error Message : " + ex.Message);
}
}
HttpContext.Current.Response.Redirect(HttpContext.Current.Request.ApplicationPath+"default/index.htm");
Or you can use this way.
HttpContext.Current.Response.Redirect is trying to send users to the wrong place
HttpContext.Current.Response.Redirect("~/default/index.htm");
There are some errors and unnecesary code in your code example:
There is no need to check if dbConn is already opened, because it was just created
The SELECT * caused an Exception when doing later an ExecuteScalar because the table has more than one column. You should change it to SELECT COUNT(*)
Because how Microsoft handles how the flow of the page is done, if you don't end the response when doing the Response.Redirect you may need to catch an ThreadAbortException. To end the response you could check Redirect(string url, bool endResponse) overload
That being said, you should do use parametrized queries, because unexpected or malicious input could cause you problems.
This question already has answers here:
ASP.NET Identity 2.0 check if current user is in role IsInRole
(4 answers)
Unable to configure AspNet.Identity using PostgreSQL
(2 answers)
Closed 4 years ago.
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 !");
}
}
}
}
}
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.
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.
I try to create login function in ASP.NET using MySQL database and enterprise library.
First I create a database and store procedures.
spselectusertype sp
DELIMITER //
Create procedure spselectusertype(
UName varchar(50),
Pasword varchar(50)
)
BEGIN
Select UserType_ID FROM login
WHERE UName = UName AND UPasword = Pasword;
end;
splogin sp
create procedure splogin()
BEGIN
SELECT *
FROM login
WHERE UName = UName and UPasword=UPasword;
END
Then I create a class library and add these functions:
Database db = DatabaseFactory.CreateDatabase("abc");
public int UserType(string UName, string UPasword)
{
return Convert.ToInt32(db.ExecuteScalar("spselectusertype", new object[] {
UName, UPasword }).ToString());
}
public int SignInUsers(string UName, string Pasword)
{
return Convert.ToInt32(db.ExecuteScalar("splogin", new object[] { UName, Pasword }));
}
Login button code:
MySqlConnection conn = new
MySqlConnection(ConfigurationManager.ConnectionStrings["abc"].ConnectionString);
ClassLibrary1.Class1 LOGIN = new ClassLibrary1.Class1();
protected void Button1_Click1(object sender, EventArgs e)
{
//UsertpeTID sve in session
int users = LOGIN.UserType(TextBox1.Text, TextBox2.Text);
//UserID Save in Session
int user_id = Convert.ToInt16(LOGIN.SignInUsers(TextBox1.Text, TextBox2.Text));
Session["UserID"] = user_id;
if (Session["UserID"] != null)
{
user_id = Convert.ToInt32(Session["UserID"].ToString());
}
if (users == 1)
{
Session["Login2"] = TextBox1.Text;
Session["Login3"] = TextBox2.Text;
Session["UserTypeID"] = users;
Response.Redirect("alldocuments.aspx");
}
else if (users == 2)
{
Session["Login2"] = TextBox1.Text;
Session["Login3"] = TextBox2.Text;
Session["UserTypeID"] = users;
Response.Redirect("Home.aspx");
Label3.Visible = true;
Label3.Text = "Incorrect User Name or Password";
}
}
}
}
But when I debug my project and enter username and password, it shows me following error
Parameter discovery is not supported for connections using GenericDatabase. You must specify the parameters explicitly, or configure the connection to use a type deriving from Database that supports parameter discovery.
on this line:
return Convert.ToInt32(db.ExecuteScalar("spselectusertype", new object[] {
UserName, UserPassword }).ToString());
So where is the mistake?
PLEASE, if you're going to develop an ASP.NET website with login, DO NOT ROLL YOUR OWN SYSTEM (unless you know what you're doing).
What I see from your system, you have barely any seurity of any kind, including role management, folder access management, password hashing and password resets. If you use an ASP.NET membership system (just start a new asp.net web forms application using Visual Studio), you get all that, plus an easy way to manage it all through a local web portal, including the option to select your own database type through the web configuration tool.
Assuming, of course, you have the option to use this, I would start with using this system, because it's a really good basis to start from.
I realize this doesn't answer your question directly, but I still feel like I should suggest it.
Error involves in the
Database db = DatabaseFactory.CreateDatabase("abc");
Since It is only supposed to support SQLServers
Reference
Reference Link
Please consider other ways to connect with the database.
Hie, I'm having a bit of a crisis trying to run an sql query from a C# class. It was working fine in the Login page it was in before and I changed very little of it when I moved it over.
SQL query in class:
namespace Masca
{
public class loginc
{
// Telling the class that the page 'Login' exists.
public Login login;
....
public void Login ()
{
// connection parameters
string sqlcon = "datasource=localhost;port=3306;username = root; password = root";
//Command to carry out -This is what the exception highlights when it's thrown.
string query = "SELECT * FROM logon.login where username = '" + login.username.Text + "' and password = '" + login.password.Password + "';";
MySqlConnection con = new MySqlConnection(sqlcon);
MySqlCommand cmd = new MySqlCommand (query,con);
MySqlDataReader rdr;
con.Open();
rdr = cmd.ExecuteReader();
int count = 0;
while (rdr.Read())
{
count = count + 1;
}
if (count == 1)
{
//If the username and password match those in the database table, run the method 'login' in the login page cs.
login.login();
}
else
{
// if they don't match, run the method 'failLogin' in the login page cs.
login.failLogin();
}
}
In login.cs I have two textboxes and a button. One for the username and one for the password. The button is supposed to trigger the above code:
public void Logon_Click(object sender, RoutedEventArgs e)
{
loginc.Login();
}
Which it does fine. However I get the classic "Object reference not set to an instance of an object" exception thrown on the query. When I enter the actual credentials instead of '+ login.username.Text +' and '+ login.password.Password +' then the exception gets thrown on 'login.Login()'.
I don't understand why the loginc.cs class refuses to relate to the login.cs but the login.cs clearly has no problem triggering the method in class the same way. Anyone know where I'm going wrong?
I see no code where you instantiate Login login. You should really do that.
Login login = new Login();
or something alike.
I need to create login page in asp.net where i have to create 3 user access levels such as
users who can view there email and updates
superusers who can view there email, updates and also delete some users
admin who can view all and delete superusers as well.
my login page has
username
password and login button
when the user/admin/superuser clicks on the button it should automatically redirect him depending on the user levels.
i have a database of username, password, userid, useraccesstype, email.
my problem here is i am not getting how to write the if commands basing on the useraccesstype in a disconnected architecture of database and also without using stored procedures.
String Uid = TextBox1.Text;
String Pwd = TextBox2.Text;
SqlConnection con = new SqlConnection(#"Data Source=Sun-PC\SQLEXPRESS;Initial Catalog=dts;Persist Security Info=True;User ID=sa;Password=********;");
SqlDataAdapter da;
da = new SqlDataAdapter("Select userid,password,useraccesstype from Table2 WHERE userid = " + Uid + " and password ='" + Pwd + "'", con);
DataSet ds = new DataSet("Table2");
da.Fill(ds, "Table2");
if (Uid == "userid" && Pwd == "password")
{
if (uzrtype3 = "componentadmin")
{
Response.Redirect("userpage.aspx");
}
if (uzrtype = "user")
{
Response.Redirect("register.aspx");
}
}
else
{
Label123.Text = "Sorry, user not recognized - please try again";
}
Reading between the lines, I think you are asking "how t get the useraccesstype"? If so with the current code, maybe:
if(ds.Tables[0].Rows.Count == 1) {
// match
var accessType = ({appropriate cast here})ds.Tables[0].Rows[0]["useraccesstype"];
} else {
// no match
}
However! I would do it a different way, solving the various parameter issues and making it much safer - using "dapper-dot-net" for convenience (google it):
string userid = ....
string password = ...
var row = con.Query(
"Select useraccesstype from Table2 WHERE userid = #userid and password = #password",
new { userid, password }).FirstOrDefault();
if(row == null) {
// no match
} else {
var accessType = ({some cast here})row.useraccesstype;
}
The salted hashing of passwords is also something you should look into.
No point returning the userid/password : you already know those. You could also use ExecuteScalar, but then you need to handle the parameters yourself.