网站权限控制

本文介绍了在开发ASP.NET在线考试系统时遇到的用户权限控制问题,包括用户验证、角色权限区分、防止未授权访问等。通过创建不同文件夹隔离内容、使用Application全局变量或数据库存储SessionID来实现权限管理,确保系统安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近开始接触asp.net,开发一个在线考试系统,其中涉及到用户管理和权限控制,要求如下:

1. 用户需要经过验证方能进入系统;

2. 不同级别的用户登录后看到的内容不同;

3. 管理员可进行管理操作,如角色、用户、权限的增删改查;

4. 防止非系统用户直接在地址栏输入某一页面地址进入系统,从而绕过登录页面;

5. 防止低权限用户登录系统后在地址栏输入高权限用户才能访问的某一页面地址,从而实现越权访问;

6. 同一用户多地登录,则后登录的挤掉先登录的,类似 QQ

对于第2个问题可以采用重定向的方法来解决

在网站创建Admin和Tester两个文件夹,分别存放管理员和考试人员使用的文件,然后在登录界面进行重定向。

 //返回重定向URL
        string returnUrl = FormsAuthentication.GetRedirectUrl(loginUser.UserID, false);
        if (returnUrl.Equals(FormsAuthentication.DefaultUrl))
        {
            //根据角色,确定跳转页面
            if (RoleCheck.IsAdmin())
                returnUrl = "~/Admin/Default.aspx";
            else
                returnUrl = "~/Tester/Default.aspx";

        }
        //重新定向到指定的URL页面
        Response.Redirect(returnUrl);

对于第4个问题可以采用Session来实现,在本项目中新建一个SessionClass类,在里面实现两个获取和设置UserID的方法

 public static Entity.User GetLoginUser()
    {
        if (null == HttpContext.Current.Session["loginUser"])
            return null;
        return (Entity.User)Tool.SerializeHelper.DeserializeObject(HttpContext.Current.Session["loginUser"].ToString());
    }

    public static void SetLoinUser(Entity.User loginUser)
    {
        if(loginUser!=null)
            HttpContext.Current.Session["loginUser"] =Tool.SerializeHelper.SerializeObject(loginUser);
    }

对于第5个问题,本项目新建一个RoleCheck类,对登录人员进行验证

public static class RoleCheck
{

    private const string ADMIN_ROLE = "管理员";
    public static bool IsAdmin()
    {
        Entity.User user=SessionClass.GetLoginUser();
        if (user != null)
        {
            foreach (string right in user.RightList)
            {
                if(ADMIN_ROLE.Equals(right.Trim()))
                    return true;
            }
        }
        return false;
    }

    /// <summary>
    /// 拒绝非管理员用户的登录,拒绝后将跳转到登陆页面
    /// </summary>
    public static void DenyLogin()
    {
        if (!IsAdmin())
            HttpContext.Current.Response.Redirect(string.Format("~/LoginSystem.aspx?errorMsg={0}","您的权限不是管理员,无法访问该页面!(也有可能是登录超时,请重新登录)"));
    }
}

对于最后一个问题,通过SessionID和用户名来保证同一用户不能同时登录。步骤如下:

1.采用Application全局变量来存储SessionID和用户名,每次登录时都保存,并且将Application保存到Hashtable中,当用户登录成功后,首先判断该用户是否已经存储在Application中,如果存在(说明已经登录),则将该用户对应的值设置为XX。

protected void loginbtn_Click(object sender, EventArgs e)  
     {  
         //登录成功。。。。。。。  
         Hashtable hOnline = (Hashtable)Application["Online"];// 读取全局变量  
         if (hOnline != null)  
         {  
             IDictionaryEnumerator idE =  hOnline.GetEnumerator();  
             string strKey = "";  
             while (idE.MoveNext())  
             {  
                 if (idE.Value != null &&  idE.Value.ToString().Equals(UserID))//如果当前用户已经登录,  
                 {  
                     //already login  
                     strKey = idE.Key.ToString();  
                     hOnline[strKey] = "XX";//将当前用 户已经在全局变量中的值设置为XX  
                     break;  
                 }  
             }  
         }  
         else  
         {  
             hOnline = new Hashtable();  
         }  
         hOnline[Session.SessionID] = UserID;//初始化当前用户的   
         Application.Lock();  
         Application["Online"] = hOnline;  
         Application.UnLock();  
         Response.Redirect("main.aspx");  
     }  

2,写一个BasePage加一个Init方法如下,系统的所有页面(除了登录和退出页面)均继承自该BasePage类

protected override  void OnInit(EventArgs e)  
   {  
       Hashtable hOnline = (Hashtable)Application["Online"];//获取已经存储的application值  
       if(hOnline != null)  
       {  
        IDictionaryEnumerator idE = hOnline.GetEnumerator();  
        while(idE.MoveNext())  
        {  
             if(idE.Key != null && idE.Key.ToString().Equals(Session.SessionID))  
             {  
                  if (idE.Value != null && "XX".Equals(idE.Value.ToString()))//说明在别处登录  
                  {  
                       hOnline.Remove(Session.SessionID);  
                       Application.Lock();  
                       Application["Online"] = hOnline;  
                       Application.UnLock();  
                       Response.Write("script type="text/javascript">  
                       alert('你的帐号已在别处登陆,你被强迫下线!');top.location.href='Default.aspx';window.close();</script>");                        Response.Redirect("Default.aspx");  
                       Response.End();                    
                  }                   
                
             }  
              
        }  
   }  
3.在程序退出后从Application中清除当前SessionID

void Session_End(object sender, EventArgs e)   
{  
        // 在会话结束时运行的代码。   
        // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为  
        // InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer   
        // 或 SQLServer,则不会引发该事件。  
        Hashtable hOnline = (Hashtable)Application["Online"];  
        if (hOnline[Session.SessionID] != null)  
        {  
            hOnline.Remove(Session.SessionID);//清除当前SessionID  
            Application.Lock();  
            Application["Online"] = hOnline;  
            Application.UnLock();  
        }  
}  

4.如果程序非正常退出,SessionID没有及时的清除,那么也不会影响帐号的正常登录,而SessionID也会随着Session的过期而自动清除,服务器也不会有压力。

5,如果感觉存储在Application中感觉不好,也可以将SessionID存入数据库中,判断方法和上面一样。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值