asp.net自定义用户身份验证与主页
本文关键字:主页 身份验证 用户 net 自定义 asp | 更新日期: 2023-09-27 18:19:40
我正在开发一个小型库存管理系统。我几乎已经在我的本地机器上创建了它。它按设计工作。我刚把它转移到我的托管帐户,现在我面临一些问题。
1、登录后,当用户转到不同的页面时,打开和关闭表单,一段时间后重定向到登录页面。我不知道为什么。似乎发生了某种异常,或者会话已清空。如何处理这种情况?
2、这是使用母版页的check-in Page_Load事件来检查用户登录的正确方法吗?
我的网站使用了一个母版页,它有单独的顶部导航菜单和底部正文区域布局。当用户第一次登录网站时,它会登录到系统中,成功登录后,我会将他的信息存储在会话中。我在所有页面中都大量使用Session进行添加、删除、更新。当执行添加记录时,我会在会话中传递失败成功消息,以便在发布后显示。登录页面的代码如下:
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;
}
}
}
我一直在检查会话是否不包含任何用户id,然后将其重定向到登录页面。我的主页后面的代码如下:
protected void Page_Load(object sender, EventArgs e)
{
if (Session[Constant.Session.LOGIN_USER_ID] == null)
{
FormsAuthentication.RedirectToLoginPage();
return;
}
CheckDBConnection();
Initialize();
}
如有任何帮助或提示,我们将不胜感激。
你可以在这里查看网站:www.paracha.net(如果有人感兴趣,我可以在私人消息中分享客人帐户凭据)
首先,请记住会话cookie未加密,因此不应使用会话存储任何机密信息。
其次,您不应该检查每个Page_Load
上的身份验证。相反,您应该在web.config:中配置页面访问
<configuration>
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
这将保护您的所有页面,因此只有经过身份验证(即登录)的用户才能看到该页面,而所有其他用户都将重定向到登录页面。
如果您希望所有用户都可以访问某些页面(例如启动页面)或文件夹(例如图像文件夹),则为每个页面或文件夹添加一个部分:
<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>
为了实现这一点,您应该使用表单身份验证。以下是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>
显然,您需要一个login.aspx页面,当您单击登录按钮时,您需要对用户进行如下身份验证:
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;
}
}
函数ValidateUser()
可以执行任何您想要的身份验证操作。如果愿意,您可以根据数据库验证凭据。
如果使用FormsAuthentication,则不需要手动检查Session[Constant.Session.LOGIN_USER_ID]
。它将自动重定向到登录页面,您可以在web.config.中对此进行配置
另一个想法
这与你的问题没有直接关系。这只是一种替代方法。
您可以创建自定义上下文来跟踪当前登录用户的信息,而不是创建多个会话状态
例如,您可以将公司和会计年度属性存储在MyUser类中。
void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (HttpContext.Current.User != null &&
HttpContext.Current.User.Identity.IsAuthenticated)
{
MyContext.Current.MyUser =
YOUR_BLL.GetUserByUsername(HttpContext.Current.User.Identity.Name);
}
}
public class MyContext
{
private MyUser _myUser;
public static MyContext Current
{
get
{
if (HttpContext.Current.Items["MyContext"] == null)
{
MyContext context = new MyContext();
HttpContext.Current.Items.Add("MyContext", context);
return context;
}
return (MyContext) HttpContext.Current.Items["MyContext"];
}
}
public MyUser MyUser
{
get { return _myUser; }
set { _myUser = value; }
}
}
}
添加
C#是强类型语言,所以不应该用变量的类型来编码变量名。例如objLoginBL和iRetVal。请阅读C#设计指南或Essential C#6.0(第7页)。