使用 forms 身份验证,避免重复造轮子
最近开始一个小 asp.net 项目,整个项目需要登录才能操作。以前大家都采用 asp 的方式 session + cookie 来实现身份验证,我一直对 asp.net 自带的 forms 验证早就耳闻,苦于没实践,今天刚好逮到机会实际应用一下。
问题:大家都说使用 forms 验证无法得到当前登录用户除了用户名之外的更多信息,经过我的一番小试验,在 forms 方式下自带的 userdata 可以为我们施展天地的地方。下面记录一下我的操作步骤备忘。
step 1: web.config 配置关键地方:
问题:大家都说使用 forms 验证无法得到当前登录用户除了用户名之外的更多信息,经过我的一番小试验,在 forms 方式下自带的 userdata 可以为我们施展天地的地方。下面记录一下我的操作步骤备忘。
step 1: web.config 配置关键地方:
web.config配置
1 <!--
2 通过 <authentication> 节可以配置 ASP.NET 用来
3 识别进入用户的
4 安全身份验证模式。
5 -->
6 <authentication mode="Forms">
7 <forms loginUrl="login.aspx" defaultUrl="index.aspx"
8 name=".ztinfozero" path="/Manager"
9 slidingExpiration="true" timeout="10"></forms>
10 </authentication>
11 <authorization>
12 <deny users="?"/>
13 </authorization>
14
<!-- 实现自定义的 rolemanager 后需配置 :
<roleManager defaultProvider="providerName(类名)"
cookieName="role" cookiePath="/" enabled="true"
cookieTimeout="30" cookieSlidingExpiration="true"
cookieRequireSSL="false" cookieProtection="All"
cacheRolesInCookie="true">
<providers>
<clear />
<add name="providerName(类名)" type="providerName(类名)" />
</providers>
</roleManager>
-->
2 通过 <authentication> 节可以配置 ASP.NET 用来
3 识别进入用户的
4 安全身份验证模式。
5 -->
6 <authentication mode="Forms">
7 <forms loginUrl="login.aspx" defaultUrl="index.aspx"
8 name=".ztinfozero" path="/Manager"
9 slidingExpiration="true" timeout="10"></forms>
10 </authentication>
11 <authorization>
12 <deny users="?"/>
13 </authorization>
14
<!-- 实现自定义的 rolemanager 后需配置 :
<roleManager defaultProvider="providerName(类名)"
cookieName="role" cookiePath="/" enabled="true"
cookieTimeout="30" cookieSlidingExpiration="true"
cookieRequireSSL="false" cookieProtection="All"
cacheRolesInCookie="true">
<providers>
<clear />
<add name="providerName(类名)" type="providerName(类名)" />
</providers>
</roleManager>
-->
step 2: 构造 SiteUser Model
TopicUser Model
[Serializable]
public class TopicUser
{
public TopicUser() { }
model
}
public class TopicUser
{
public TopicUser() { }
model
}
step 3: 创建用户登录代码:
数据库-用户登录方法
step 4 : 创建登录页:
代码
protected void btnOK_Click(object sender, EventArgs e)
{
string username = tbname.Text.Trim();
string pass = tbpass.Text.Trim();
if (!string.IsNullOrEmpty(username)) {
if (!string.IsNullOrEmpty(pass)) {
DataService.User b = new DataService.User();
DataService.TopicUser user = b.UserLogon(username, pass);
if (user != null) {
//roles , userid | userchname
string userdata = string.Format("{0},{1}|{2}",
user.UserPermit, user.autoID, user.UserChName);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, username, DateTime.Now, DateTime.Now.AddHours(2),
true, userdata);
string encticket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(
FormsAuthentication.FormsCookieName, encticket);
Response.Cookies.Add(cookie);
Response.Redirect("Index.aspx");
}
}
}
}
{
string username = tbname.Text.Trim();
string pass = tbpass.Text.Trim();
if (!string.IsNullOrEmpty(username)) {
if (!string.IsNullOrEmpty(pass)) {
DataService.User b = new DataService.User();
DataService.TopicUser user = b.UserLogon(username, pass);
if (user != null) {
//roles , userid | userchname
string userdata = string.Format("{0},{1}|{2}",
user.UserPermit, user.autoID, user.UserChName);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, username, DateTime.Now, DateTime.Now.AddHours(2),
true, userdata);
string encticket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(
FormsAuthentication.FormsCookieName, encticket);
Response.Cookies.Add(cookie);
Response.Redirect("Index.aspx");
}
}
}
}
step 5: 在 global.asax 里添加 Application_AuthenticateRequest 事件以设置当前登录用户的信息:
Application_AuthenticateRequest
/*****
using System;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
*****/
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
if (context.Request.IsAuthenticated) {
FormsIdentity id = context.User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = id.Ticket;
string[] roles = ticket.UserData.Split(',');
/*
* 将原有的Identity加上角色信息新建一个GenericPrincipal表示当前用户
* 这样当前用户就拥有了role信息
* 据此在web.config中用role来控制用户的访问权限了.
*/
context.User = new GenericPrincipal(id, roles);
}
old
}
using System;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
*****/
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
if (context.Request.IsAuthenticated) {
FormsIdentity id = context.User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = id.Ticket;
string[] roles = ticket.UserData.Split(',');
/*
* 将原有的Identity加上角色信息新建一个GenericPrincipal表示当前用户
* 这样当前用户就拥有了role信息
* 据此在web.config中用role来控制用户的访问权限了.
*/
context.User = new GenericPrincipal(id, roles);
}
old
}
step 6: 如何得到当前登录用户的信息
CurrentUser
public static TopicUser CurrentUser {
get {
DataService.TopicUser user = new DataService.TopicUser();
FormsIdentity identity = HttpContext.Current.User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = identity.Ticket;
string userdata = ticket.UserData; //获取自定义的 UserData 串
if (!string.IsNullOrEmpty(userdata)) {
if (userdata.IndexOf(',') > 0 && userdata.IndexOf('|') > 0)
{
//roles , userid | userchname
string uinfo = userdata.Split(',')[1];
string[] u = uinfo.Split('|');
int uid = 0;
int.TryParse(u[0], out uid);
user.autoID = uid;
user.UserChName = u[1];
user.UserName = HttpContext.Current.User.Identity.Name;
}
}
return user;
}
}
get {
DataService.TopicUser user = new DataService.TopicUser();
FormsIdentity identity = HttpContext.Current.User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = identity.Ticket;
string userdata = ticket.UserData; //获取自定义的 UserData 串
if (!string.IsNullOrEmpty(userdata)) {
if (userdata.IndexOf(',') > 0 && userdata.IndexOf('|') > 0)
{
//roles , userid | userchname
string uinfo = userdata.Split(',')[1];
string[] u = uinfo.Split('|');
int uid = 0;
int.TryParse(u[0], out uid);
user.autoID = uid;
user.UserChName = u[1];
user.UserName = HttpContext.Current.User.Identity.Name;
}
}
return user;
}
}
由此得到当前登录用户的 ID 为 UserBase.CurrentUser.autoID ; 真实名字是: UserBase.CurrentUser.UserChName ;
判断当前用户的角色是否为管理员: HttpContext.Current.User.IsInRole("1") ; // 1 为管理员
退出当前登录的方法:
LogOut.aspx
protected void Page_Load(object sender, EventArgs e)
{
System.Web.Security.FormsAuthentication.SignOut();
Response.Write("<script>window.top.location='login.aspx';</script>");
Response.End();
}
{
System.Web.Security.FormsAuthentication.SignOut();
Response.Write("<script>window.top.location='login.aspx';</script>");
Response.End();
}
至此,身份验证完成。我们不用费尽心思在四处堆放用户是否登录判断的代码了。