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(如果有人感兴趣,我可以在私人消息中分享客人帐户凭据)

asp.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页)。