C# 基于列表表单的角色身份验证和隐藏菜单项

C# 基于列表表单的角色身份验证和隐藏菜单项,c#,asp.net,forms-authentication,roles,C#,Asp.net,Forms Authentication,Roles,我正在开发一个intranet web应用程序(asp.net和C#),现在我已经达到了安全和访问控制的里程碑 该应用程序具有: Login.aspx页面(公司内任何人都可以访问) Home.aspx页面(仅在登录后访问),左侧有一个包含所有部门页面的菜单和一个不会启动的注销按钮 多个部门页面 现在,我通过应用程序使用的数据库上的“用户”表(FORMS AUTHENTICATION)让登录系统工作,然而,在搜索了一段时间后,我不知道如何实现角色以限制对部门页面的访问并隐藏菜单选项 以下是VS

我正在开发一个intranet web应用程序(asp.net和C#),现在我已经达到了安全和访问控制的里程碑

该应用程序具有:

  • Login.aspx页面(公司内任何人都可以访问)
  • Home.aspx页面(仅在登录后访问),左侧有一个包含所有部门页面的菜单和一个不会启动的注销按钮
  • 多个部门页面
现在,我通过应用程序使用的数据库上的“用户”表(FORMS AUTHENTICATION)让登录系统工作,然而,在搜索了一段时间后,我不知道如何实现角色以限制对部门页面的访问并隐藏菜单选项

以下是VS Express for Web中的解决方案结构:

“用户”表记录如下所示,如您所见,James很特别,可以访问多个页面:

我计划采用以下方案:

  • 用户只能访问其部门页面

  • 某些用户可以访问其他部门的页面

我知道我必须在web配置上有这样的功能,但是如果我有表单身份验证,我该如何实现它呢

<location path="Marketing.aspx">
<system.web>
    <authorization>
        <deny roles="AD\Grupo Planeamento"/>
        <allow roles="AD\Grupo Marketing"/>
    </authorization>
</system.web>
Home.aspx

<asp:Content ID="rightcontentdown" ContentPlaceHolderID="rightcontentdown" Runat="Server">
    <asp:Button runat="server" Text="Terminar Sessão" ID="SignOutButton" OnClick="Signoutbutton_click" />
</asp:Content>

首先创建PagesByDepartment表和department表,如下所示:

    • Id(int)
    • 名称(字符串)
  • PagesByDepartment
    • Id(int)
    • 部门ID(内部)
    • 页面名称(字符串)
  • 使用者
    • Id(int)
    • 用户名(字符串)
    • 密码(字符串)-如果可以将其散列到位数组中会更好:)
    • 部门ID(内部)
您需要在所有页面的每个请求中授权用户,对我来说,可以自定义用户的主要对象

例如:

public class MyAppPrincipal :IPrincipal, IMyAppPrincipal
      {
            private IIdentity _identity;
            private string _department;
            public MyAppPrincipal( IIdentity identity, department)
            {
                  _identity = identity;
                  _department = department;
            }

            public bool IsPageEnabled(string pageName)
            {
                //DB is your access to your database, I know that you´re using plain ADO.NET here so put query here or cache the elements in your app_start and read them from it....
                //let´s say you have a method that you pass the pagename and the department
                 return DB.IsPageEnabled( pageName, this._department);

            }
        }
将部门添加到自定义用户数据中的身份验证票证中,如下所示

protected void LoginButton_Click(object sender, EventArgs e)
{
    if (ValidateUser(UserNameTextBox.Value, PasswordTextBox.Value))
         {
                 // get the department from your DB
                 string department = DB.GetDepartmentByUsername(UserNameTextBox.Value);

                 FormsAuthenticationTicket tkt;
                 string cookiestr;
                 HttpCookie ck;

                          tkt = new FormsAuthenticationTicket(2,  // version 
                          UserNameTextBox.Value, 
                          DateTime.Now, 
                          DateTime.Now.AddMinutes(30), 
                          RemPassword.Checked, 
                          department, // instead of custom data
                          FormsAuthentication.FormsCookiePath);

                 cookiestr = FormsAuthentication.Encrypt(tkt);
                 ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr);
                 if (RemPassword.Checked)
                 ck.Expires = tkt.Expiration;
                 ck.Path = FormsAuthentication.FormsCookiePath;
                 Response.Cookies.Add(ck);

                 string strRedirect;
                 strRedirect = Request["ReturnUrl"];
                 if (strRedirect == null)
                 strRedirect = "Home.aspx";
                 Response.Redirect(strRedirect, true);
         }
                 else
                 Response.Redirect("Login.aspx", true);
}
然后您需要一个httpmodule来进行身份验证/授权

public class CustomAuthenticationModule : IHttpModule 
      { 

            public void Init(HttpApplication httpApp) 
            { 
                  httpApp.AuthorizeRequest += new EventHandler(this.AuthorizaRequest); 
                  httpApp.AuthenticateRequest += new EventHandler(this.AuthenticateRequest); 
            } 
            public void Dispose() 
            {} 

            private void AuthorizaRequest( object sender, EventArgs e) 
            {     
                  if (HttpContext.Current.User != null) 
                  { 
                         if (HttpContext.Current.User.Identity.IsAuthenticated) 
                        { 
                              if (HttpContext.Current.User is MyAppPrincipal) 
                              { 

                              MyAppPrincipal principal = (MyAppPrincipal) HttpContext.Current.User; 
                              if (!principal.IsPageEnabled(HttpContext.Current.Request.Path) ) 
                                          HttpContext.Current.Server.Transfer( "unauthorized.aspx"); 
                              } 
                        } 
                  } 
            } 

            private void AuthenticateRequest(object sender, EventArgs e) 
            { 
                  if (HttpContext.Current.User != null) 
                  { 

                        if (HttpContext.Current.User.Identity.IsAuthenticated) 
                        { 
                              if (HttpContext.Current.User.Identity is FormsIdentity) 
                              { 
                                    var id = HttpContext.Current.User.Identity; 
                                    FormsAuthenticationTicket ticket = id.Ticket; 
                                    string cookieName = System.Web.Security.FormsAuthentication.FormsCookieName; 
                                    string userData = 
                                          System.Web.HttpContext.Current.Request.Cookies[cookieName].Value; 

                                    ticket  = FormsAuthentication.Decrypt(userData); 

                                    string department=""; 
                                    if( userData.Length > 0 ) 
                                          department= ticket.UserData; 
                                    HttpContext.Current.User = new 
                                    MyAppPrincipal(_identity, department);                          
                              } 
                        } 
                  } 
            }//AuthenticateRequest 
      } //class 
}
别忘了添加自定义模块

<httpModules > 
      < add type ="myapp, SecurityModules" name ="CustomAuthenticationModule" /> 
</ httpModules > 


PD:您可以将其理解为伪代码,因为我在文本框上编码,而不是VS,我希望这有助于

只是一个想法,您是否考虑过使用单独的角色表并使用1对1关系来组织访问。这样您就可以允许Admin/Manager/User。我是否必须为角色设置单独的表?将所有内容都放在一个表中的全部意义在于,稍后创建一个管理页面,在该页面中,我们可以添加用户并分配他们的部门,从而使他们能够访问我们想要的任何内容
protected void Signoutbutton_click(object sender, EventArgs e)
{
    FormsAuthentication.SignOut();
    Session.Abandon();
    Session.Contents.RemoveAll();
    Response.Redirect("Login.aspx", true);
}
public class MyAppPrincipal :IPrincipal, IMyAppPrincipal
      {
            private IIdentity _identity;
            private string _department;
            public MyAppPrincipal( IIdentity identity, department)
            {
                  _identity = identity;
                  _department = department;
            }

            public bool IsPageEnabled(string pageName)
            {
                //DB is your access to your database, I know that you´re using plain ADO.NET here so put query here or cache the elements in your app_start and read them from it....
                //let´s say you have a method that you pass the pagename and the department
                 return DB.IsPageEnabled( pageName, this._department);

            }
        }
protected void LoginButton_Click(object sender, EventArgs e)
{
    if (ValidateUser(UserNameTextBox.Value, PasswordTextBox.Value))
         {
                 // get the department from your DB
                 string department = DB.GetDepartmentByUsername(UserNameTextBox.Value);

                 FormsAuthenticationTicket tkt;
                 string cookiestr;
                 HttpCookie ck;

                          tkt = new FormsAuthenticationTicket(2,  // version 
                          UserNameTextBox.Value, 
                          DateTime.Now, 
                          DateTime.Now.AddMinutes(30), 
                          RemPassword.Checked, 
                          department, // instead of custom data
                          FormsAuthentication.FormsCookiePath);

                 cookiestr = FormsAuthentication.Encrypt(tkt);
                 ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr);
                 if (RemPassword.Checked)
                 ck.Expires = tkt.Expiration;
                 ck.Path = FormsAuthentication.FormsCookiePath;
                 Response.Cookies.Add(ck);

                 string strRedirect;
                 strRedirect = Request["ReturnUrl"];
                 if (strRedirect == null)
                 strRedirect = "Home.aspx";
                 Response.Redirect(strRedirect, true);
         }
                 else
                 Response.Redirect("Login.aspx", true);
}
public class CustomAuthenticationModule : IHttpModule 
      { 

            public void Init(HttpApplication httpApp) 
            { 
                  httpApp.AuthorizeRequest += new EventHandler(this.AuthorizaRequest); 
                  httpApp.AuthenticateRequest += new EventHandler(this.AuthenticateRequest); 
            } 
            public void Dispose() 
            {} 

            private void AuthorizaRequest( object sender, EventArgs e) 
            {     
                  if (HttpContext.Current.User != null) 
                  { 
                         if (HttpContext.Current.User.Identity.IsAuthenticated) 
                        { 
                              if (HttpContext.Current.User is MyAppPrincipal) 
                              { 

                              MyAppPrincipal principal = (MyAppPrincipal) HttpContext.Current.User; 
                              if (!principal.IsPageEnabled(HttpContext.Current.Request.Path) ) 
                                          HttpContext.Current.Server.Transfer( "unauthorized.aspx"); 
                              } 
                        } 
                  } 
            } 

            private void AuthenticateRequest(object sender, EventArgs e) 
            { 
                  if (HttpContext.Current.User != null) 
                  { 

                        if (HttpContext.Current.User.Identity.IsAuthenticated) 
                        { 
                              if (HttpContext.Current.User.Identity is FormsIdentity) 
                              { 
                                    var id = HttpContext.Current.User.Identity; 
                                    FormsAuthenticationTicket ticket = id.Ticket; 
                                    string cookieName = System.Web.Security.FormsAuthentication.FormsCookieName; 
                                    string userData = 
                                          System.Web.HttpContext.Current.Request.Cookies[cookieName].Value; 

                                    ticket  = FormsAuthentication.Decrypt(userData); 

                                    string department=""; 
                                    if( userData.Length > 0 ) 
                                          department= ticket.UserData; 
                                    HttpContext.Current.User = new 
                                    MyAppPrincipal(_identity, department);                          
                              } 
                        } 
                  } 
            }//AuthenticateRequest 
      } //class 
}
<httpModules > 
      < add type ="myapp, SecurityModules" name ="CustomAuthenticationModule" /> 
</ httpModules >