微软的ASP.NET提供了3种用户验证方式,即Windows验证、窗体(Forms)验证和护照验证(Passport)验证。
由于验证方式各不相同,因而这3种验证方式在使用范围上也有很大的不同, Windows验证方式只适用于放在受控环境里的网站; 也就是说,更适合于企业内网(Intranet)。窗体认证特别适合布置于互联网的应用,而护照验证方式适合于跨站之间的应用,用户只用一个用户名和密码就可以访问任何成员站,并且在注销离开时,所有护照信息都会清除,你可以在公共场所放心的使用。
我们在编写Web程序时,最多用到的便是窗体(Forms)验证方式,而微软提供了只要简单的配置Web.config文件就可实现这种简单的窗体(Forms)验证。为了能更好的使用窗体验证,我对这种验证方式进行了研究。
基于表单身份验证的类的命名空间:System.Web.Security
常用的几个类分别为:
1.FormsAuthentication
作用:为 Web 应用程序管理 Forms 身份验证服务
2.FormsAuthenticationTicket
作用:提供对票证的属性和值的访问,这些票证用于 Forms 身份验证对用户进行标识
3.FormsIdentity
作用:表示一个使用 Forms 身份验证进行了身份验证的用户标识.(用户身份)
4.FormsAuthenticationModule
作用:启用 Forms 身份验证的情况下设置 ASP.NET 应用程序用户的标识
一、实现简单的验证方式
首先,我们可以通过配置Web.Config文件来实现简单的验证方式。先建立一个Web工程,然后在首页放登录控件。然后在这个工程下再建立一个目录,在这个目录下添加两个Web页面,设置成这个目录下的页面只有通过验证后再能访问。
在Default.aspx页中,输入用户名和密码,然后Click,如果密码和用户名正确,则通过验证就能转到新建目录下的一个页面上。如果没有通过验证,则不能访问目录下的页面。代码如下:
Void Logon_Click(object sender, EventArgs e)
{
String UserName = UserEmail.Text;
String UserPass = UserPass.Text;
If(通过连接数据库判断用户和密码是否正确)
{
//将经过身份验证的用户重定向回最初请求的 URL 或默认 URL
FormsAuthentication.RedirectFromLoginPage(UserName, Persist.Checkd);
//这个函数是否建立Cookie:解决:建立Cookie
Else
{
Msg.Text = Invalid credentials. Please try again.";
}
}
{
String UserName = UserEmail.Text;
String UserPass = UserPass.Text;
If(通过连接数据库判断用户和密码是否正确)
{
//将经过身份验证的用户重定向回最初请求的 URL 或默认 URL
FormsAuthentication.RedirectFromLoginPage(UserName, Persist.Checkd);
//这个函数是否建立Cookie:解决:建立Cookie
Else
{
Msg.Text = Invalid credentials. Please try again.";
}
}
然后在建立的目录下,新建一个Web.Config文件
<configuration>
<system.web>
<authorization>
<deny users="?" /> 不充许没经过身份验证的用户进行访问
</authorization>
</system.web>
</configuration>
<system.web>
<authorization>
<deny users="?" /> 不充许没经过身份验证的用户进行访问
</authorization>
</system.web>
</configuration>
在这个Web.Config文件中,设置了这个目录下所有文件的授权方式。这是一种URL授权。应用程序根据配置对匿名用户进行检查。URL授权在Web.config中的<authorization>区段内定义。
<authorization></authorization>区段中有两个标记,标记<allow>定义了许的用户、任务和操作,在<deny>标记中包含了不被充许的用户、任务和操作。
例如: <allow users = “*”>
<deny users = “?”>
“*”代表所有的用户,“?”表示匿名(没经过身份验证的)用户。
“*”代表所有的用户,“?”表示匿名(没经过身份验证的)用户。
在要目下的Web.Config中,我们同时要设置验证方式是基于Forms的
<authentication mode="Forms">
<forms loginUrl="Logon.aspx" name=".ASPXFORMSAUTH"></forms>
</authentication>
<authorization>
<allow users="*"/>
</authorization>
<forms loginUrl="Logon.aspx" name=".ASPXFORMSAUTH"></forms>
</authentication>
<authorization>
<allow users="*"/>
</authorization>
<forms>元素的有效属性
Name: 用于身份验证的Http Cookie的名称。
LoginUrl:没有通地验证的用户将要被重定向到的登录页面的URL.
Protection: Cookie数据的保护方法。
TimeOut: Cookie的过期时限,以分钟为单位。默认值为30
Path:Path用于已发出Cookie的路径。默认值为”/”。
二、实现复杂的验证方式(角色控制)
构造GenericPrincipal 和 FormsIdentity 对象
GenericPrincipal : 表示一般用户
FormsIdentity:表示一个使用 Forms 身份验证进行了身份验证的用户标识
FormsIdentity类由 FormsAuthenticationModule在通过 Forms 身份验证对用户进行身份验证时使用。使用从 Forms 身份验证 Cookie 或 URL 解密的 FormsAuthenticationTicket创建一个 FormsIdentity的实例。然后,使用此FormsIdentity类的新实例构造一个新的 GenericPrincipal 对象,该对象将设置为当前 HttpContext的 User属性的值在Global.asax文件中,添加事件Application_AuthenticateRequest代码:
注:Application_AuthenticateRequest在这个事件中添加自定义身份验证的代码。
1、页面请求时获得cookie及角色值
using System.Web.Security;
using System.Security;
//这个事件用于页面请求时获得cookie及角色值
protected void Application_AuthenticationRequest(object sender, EventArgs e)
{
//请求传递的Cookie集合中获得窗体身份验证Cookie
//FormsCookieName:获取用于存储Forms 身份验证票证的Cookie 名称
//FormsCookieName 用于引用存储FormsAuthenticationTicket 信息的Cookie
string cookiename = FormsAuthentication.FormsCookieName;
//提供创建和操作各HTTP Cookie 的类型安全方法
//HttpCookie类获取和设置各Cookie 的属性
HttpCookie cookie = Reauest.Cookies[cookiename]; /*从cookiename得到cookie*/
if (cookie == null)
return;
//从窗体身份验证cookie中提取和解密身份验证票据
FormsAuthenticationTicket ticket = null;
try
{
//返回值:一个FormsAuthenticationTicket 对象
ticket = FormsAuthentication.Decrypt(cookie.Value); //cookie:加密的身份验证票
}
catch(Exception err)
{
return;
}
if (ticket == null)
return;
//解析出用户在最初对用户进行身份验证时附加到票上的管道分隔的角色名称列表
string[] roles = ticket.UserData.Split(new char[] { ‘|‘ });
//创建一个FormsIdentity对象和一个GenericPrincipal对象。前一个对象从票名称中
//获得用户名,后一个对象将此标识与用户角色列表包含在一起
FormsIdentity ident = new FormsIdentity(ticket);
GenericPrincipal princ = new GenericPrincipal(ident, roles);
HttpContext.Current.User = princ;
}
using System.Security;
//这个事件用于页面请求时获得cookie及角色值
protected void Application_AuthenticationRequest(object sender, EventArgs e)
{
//请求传递的Cookie集合中获得窗体身份验证Cookie
//FormsCookieName:获取用于存储Forms 身份验证票证的Cookie 名称
//FormsCookieName 用于引用存储FormsAuthenticationTicket 信息的Cookie
string cookiename = FormsAuthentication.FormsCookieName;
//提供创建和操作各HTTP Cookie 的类型安全方法
//HttpCookie类获取和设置各Cookie 的属性
HttpCookie cookie = Reauest.Cookies[cookiename]; /*从cookiename得到cookie*/
if (cookie == null)
return;
//从窗体身份验证cookie中提取和解密身份验证票据
FormsAuthenticationTicket ticket = null;
try
{
//返回值:一个FormsAuthenticationTicket 对象
ticket = FormsAuthentication.Decrypt(cookie.Value); //cookie:加密的身份验证票
}
catch(Exception err)
{
return;
}
if (ticket == null)
return;
//解析出用户在最初对用户进行身份验证时附加到票上的管道分隔的角色名称列表
string[] roles = ticket.UserData.Split(new char[] { ‘|‘ });
//创建一个FormsIdentity对象和一个GenericPrincipal对象。前一个对象从票名称中
//获得用户名,后一个对象将此标识与用户角色列表包含在一起
FormsIdentity ident = new FormsIdentity(ticket);
GenericPrincipal princ = new GenericPrincipal(ident, roles);
HttpContext.Current.User = princ;
}
2、登录时可以得到用户信息以及是否已经登录
//验证及得到用户信息
private void Page_Load(object sender, System.EventArgs e)
{
FormsIdentity userIdentiy;
FormsAuthenticationTicket objTecket;
if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
userIdentiy = HttpContext.Current.User.Identity;
objTecket = userIdentiy.Ticket;
//可以从Ticket中获取用户信息
}
else
{
Response.Write("<script>alert(‘您没有登陆!‘);history.back()</script>");
//或者指向登录页面
Response.Redirect("Login.aspx");
}
}
private void Page_Load(object sender, System.EventArgs e)
{
FormsIdentity userIdentiy;
FormsAuthenticationTicket objTecket;
if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
userIdentiy = HttpContext.Current.User.Identity;
objTecket = userIdentiy.Ticket;
//可以从Ticket中获取用户信息
}
else
{
Response.Write("<script>alert(‘您没有登陆!‘);history.back()</script>");
//或者指向登录页面
Response.Redirect("Login.aspx");
}
}
3、登录时生成用户票据
private string Authorization(string username, string password)
{
//用户登录验证
string ip = System.Web.HttpContext.Current.Request.UserHostAddress;
string name = username;
string pwd = password;
if (ValidatePwd(name, pwd) = true) //数据库验证,代码略
{
//创建身份验证票证
FormsAuthenticationTicket ticker = new FormsAuthenticationTicket(1, name, DateTime.Now,
DateTime.Now.AddMinutes(30), false, "");
string encryptTicket = FormsAuthentication.Encrypt(ticker);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptTicket);
Reponse.AppendCookie(cookie);
//将用户重定向到最初的请求页面
Response.Redirect(FormsAuthentication.GetRedirectUrl(name, false));
//Resonse.Redirect(FormsAuthentication.RedirectFromLoginPage(name, false));
//this.Session["UserName"] = username;
}
else
{
Response.Write("<script>alert(‘您的用户名或密码错误‘);</script>");
}
}
{
//用户登录验证
string ip = System.Web.HttpContext.Current.Request.UserHostAddress;
string name = username;
string pwd = password;
if (ValidatePwd(name, pwd) = true) //数据库验证,代码略
{
//创建身份验证票证
FormsAuthenticationTicket ticker = new FormsAuthenticationTicket(1, name, DateTime.Now,
DateTime.Now.AddMinutes(30), false, "");
string encryptTicket = FormsAuthentication.Encrypt(ticker);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptTicket);
Reponse.AppendCookie(cookie);
//将用户重定向到最初的请求页面
Response.Redirect(FormsAuthentication.GetRedirectUrl(name, false));
//Resonse.Redirect(FormsAuthentication.RedirectFromLoginPage(name, false));
//this.Session["UserName"] = username;
}
else
{
Response.Write("<script>alert(‘您的用户名或密码错误‘);</script>");
}
}
解释:
Context.User.Identity.IsAuthenticated
Context:获取与该页关联的 System.Web.HttpContext 对象
User:为当前 HTTP 请求获取或设置安全信息
Identity:获取当前用户的标识
IsAuthenticated:获取一个bool值,该值指示是否验证了用户