C# 基于列表表单的角色身份验证和隐藏菜单项
我正在开发一个intranet web应用程序(asp.net和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
- Login.aspx页面(公司内任何人都可以访问)
- Home.aspx页面(仅在登录后访问),左侧有一个包含所有部门页面的菜单和一个不会启动的注销按钮
- 多个部门页面
- 用户只能访问其部门页面
- 某些用户可以访问其他部门的页面
<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 >