I am working on a small Inventory management system. I have almost created it on my local machine. It works as it is designed. I just moved it to my hosting account and now I am facing some problems.
1, After login, when user goes to different pages, open and closes forms, after some time it redirects to login page. I don't know why. Seems like some sort of exception was occurred or the session had gone empty. How to handle this condition?
2, Is this the right way to keep a check on the user login using a check in Page_Load event of master page?
My site uses a master page that has separate layout for top navigation menu and bottom body area. When the first time user lands on the site it login into the system and upon successful login I store his information in session. I am heavily using Session in all pages for ADD, DELETE, UPDATE purposes. When an add record is performed, I pass success of failure message in session to show after post back. Code behind of login page is given below:
protected void loginForm_OnAuthenticate(object sender, AuthenticateEventArgs e)
{
string error = "";
sMethodName = "loginForm_OnAuthenticate";
_objLoginBLL = new LoginBLL();
int iRetVal = _objLoginBLL.ValidateUser(loginForm.UserName, loginForm.Password, ref error);
if (iRetVal >= 0)
{
Session.Clear(); //Remove all stored Session variables.
Session[Constant.Session.LOGGED_IN_DATETIME] = DateTime.Now.ToString("yyyyMMddHHmmssfff");
Session[Constant.Session.LOGIN_USERNAME] = loginForm.UserName;
Session[Constant.Session.LOGIN_USER_ID] = iRetVal;
Session[Constant.Session.LOGIN_COMPANY] = ddlCompanies.SelectedValue;
Session[Constant.Session.LOGIN_FISCAL_YEAR] = ddlFiscalYear.SelectedValue;
Session[Constant.Session.IS_DIRECT_ACCESS] = "NO";
FormsAuthentication.RedirectFromLoginPage(loginForm.UserName, loginForm.RememberMeSet);
}
else
{
Logger.Log("User validation failed.", sClassName, sMethodName, DEBUG);
switch (iRetVal)
{
case -1:
loginForm.FailureText = Constant.Messages.INCORRECT_USER_OR_PASSWORD;
loginForm.Focus();
break;
case -2:
loginForm.FailureText = Constant.Messages.ACCOUNT_LOCKED;
loginForm.Focus();
break;
//case -3:
//TODO: Account doesn't exists
default:
var randToken = new Random().Next(1000);
Session[Constant.Session.TOKEN] = randToken;
var myHashtable = new Hashtable
{
{Constant.Session.TOKEN, randToken},
{Constant.Fields.ERROR_KEY, iRetVal}
};
Response.Redirect(WebFunctions.CreateQueryString(Constant.Urls.Error, myHashtable));
break;
}
}
}
I am continuously checking if the session doesn't contain any user id then redirect it to the login page. The code behind of my master page is given below:
protected void Page_Load(object sender, EventArgs e)
{
if (Session[Constant.Session.LOGIN_USER_ID] == null)
{
FormsAuthentication.RedirectToLoginPage();
return;
}
CheckDBConnection();
Initialize();
}
Any help or tips will be appreciated.
You can view the site here: www.paracha.net (I can share guest account credentials in private message if anyone is interested)
First of all, keep in mind that the session cookie is not encrypted, so you should not be using the session to store any confidential information.
Secondly, you should not be checking the authentication on every Page_Load
. Instead, you should configure the page access in web.config:
<configuration>
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
This will protect all your pages so only authenticated (i.e. logged in) users will see the page, while all others will be redirected to the login page.
If you have some pages (e.g. a splash page) or folders (e.g. the images folder) that you want them to be accessible to all users, then add a section for each page or folder:
<configuration>
<location path="splash.aspx">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
<location path="images">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
</configuration>
In order for this to work, you should be using forms authentication. Here are the settings in web.config:
<configuration>
<system.web>
<authentication mode="Forms">
<forms
name=".YOURNAME_AUTH"
loginUrl="login"
defaultUrl="/"
protection="All"
timeout="30"
path="/"
requireSSL="true"
slidingExpiration="true"
cookieless="UseCookies"
domain=""
enableCrossAppRedirects="false">
</forms>
</authentication>
</system.web>
</configuration>
Obviously, you will need a login.aspx page, and when you click the Log in button, you need to authenticate the user like this:
protected void btnLogIn_Click(object sender, EventArgs e) {
string Username = txtUsername.Text;
string Password = txtPassword.Text;
try {
if (ValidateUser(Username, Password)) {
FormsAuthentication.RedirectFromLoginPage(Username, false);
}
else {
lblMessage.Text = "Incorrect Credentials.";
lblMessage.ForeColor = Color.Red;
}
}
catch {
lblMessage.Text = "Login Failed.";
lblMessage.ForeColor = Color.Red;
}
}
The function ValidateUser()
can do anything you want for authentication. You can validate the credentials against your database if you like.