ASP.NET2.0中提供的身份验证提供程序,对1.1中的验证机制进行了封装,并且和Login等控件结合使用,十分方便.但是它也有一些缺点:不易扩展,需要要一些特殊的表来存储这些信息等等.
当然,你也可以通过重写Provider,不过这个工作量实在很大,而且重写后的Provider的复用性不高,下面我就介绍一下自己动手实现身份验证.
我们分以下几种情况来讨论:
1.用户名和密码存放在web.config中
1<configuration>
2 <system.web>
3 <authentication mode="Forms">
4 <credentials passwordFormat="Clear">
5 <user name="Jim" password="Jim"/>
6 <user name="Mike" password="Mike"/>
7 </credentials>
8 </authentication>
9 </system.web>
10</configuration>
2 <system.web>
3 <authentication mode="Forms">
4 <credentials passwordFormat="Clear">
5 <user name="Jim" password="Jim"/>
6 <user name="Mike" password="Mike"/>
7 </credentials>
8 </authentication>
9 </system.web>
10</configuration>
protected void btnLogin_Click(object sender, EventArgs e)
{
if (FormsAuthentication.Authenticate(username, password))
{
FormsAuthentication.RedirectFromLoginPage(username, true);
}
else
{
Response.Write("<script>alert('Wrong username or password');</script>");
}
}
简单的几行代码,就实现了用户身份验证,其中用户密码可以采用Clear,SHA1,MD5三种格式,.NET自己会进行相应的转换,你只要在web.config中配置好,输入密码的时候还按最初的明码输入就行了.如下:{
if (FormsAuthentication.Authenticate(username, password))
{
FormsAuthentication.RedirectFromLoginPage(username, true);
}
else
{
Response.Write("<script>alert('Wrong username or password');</script>");
}
}
<!--<credentials passwordFormat="Clear">
<user name="Jim" password="Jim"/>
<user name="Mike" password="Mike"/>
</credentials>-->
<credentials passwordFormat="SHA1">
<user name="Jim" password="7627F9952B9C378EDC494C5751804403E5973074"/>
<user name="Mike" password="D6AC022931A66A2BCC244DB91818EBEC76CE5E18"/>
</credentials>
<!--
<credentials passwordFormat="MD5">
<user name="Jim" password="D54B3C8FCD5BA07E47B400E69A287966"/>
<user name="Mike" password="1B83D5DA74032B6A750EF12210642EEA"/>
</credentials>
-->
2.采用其他验证方法<user name="Jim" password="Jim"/>
<user name="Mike" password="Mike"/>
</credentials>-->
<credentials passwordFormat="SHA1">
<user name="Jim" password="7627F9952B9C378EDC494C5751804403E5973074"/>
<user name="Mike" password="D6AC022931A66A2BCC244DB91818EBEC76CE5E18"/>
</credentials>
<!--
<credentials passwordFormat="MD5">
<user name="Jim" password="D54B3C8FCD5BA07E47B400E69A287966"/>
<user name="Mike" password="1B83D5DA74032B6A750EF12210642EEA"/>
</credentials>
-->
如果你的用户密码存在数据库中或者其他存储介绍中,就要自己写验证逻辑了
if (密码正确)
{
FormsAuthentication.RedirectFromLoginPage(username, true);
}
else
{
Response.Write("<script>alert('Wrong username or password');</script>");
}
3.扩展Context.User{
FormsAuthentication.RedirectFromLoginPage(username, true);
}
else
{
Response.Write("<script>alert('Wrong username or password');</script>");
}
通常情况下,我们可以通过Context.User或者Page.User来获取当前登录用户的信息,这个一个实现了IPrinciple的类,默认类型是GenericPriciple,这个类存储的信息十分有限,下面我们尝试自定义一个IPrinciple.
比如我想在User中存储QQ号码的相关信息,声明一个类myUser如下:
public class myUser : IPrincipal
{
private string _authenticationType;
private bool _isAuthenticated;
private string _name;
private myUser()
{ }
public myUser(string authenticationType, bool isAuthenticate, string name)
{
_authenticationType = authenticationType;
_isAuthenticated = isAuthenticate;
_name = name;
switch (_name.ToUpper())
{
case "JIM":
_qq = "123456789";
break;
default:
_qq = "987654321";
break;
}
}
private string _qq;
public string QQ
{
get { return _qq; }
set { _qq = value; }
}
IPrincipal Members
}
{
private string _authenticationType;
private bool _isAuthenticated;
private string _name;
private myUser()
{ }
public myUser(string authenticationType, bool isAuthenticate, string name)
{
_authenticationType = authenticationType;
_isAuthenticated = isAuthenticate;
_name = name;
switch (_name.ToUpper())
{
case "JIM":
_qq = "123456789";
break;
default:
_qq = "987654321";
break;
}
}
private string _qq;
public string QQ
{
get { return _qq; }
set { _qq = value; }
}
IPrincipal Members
}
接着我们要给Context.User赋值,由于ASP.NET是无状态的,所以要在每次请求页面的时候,判断当前用户是否通过验证,如果通过验证,抓取相关信息,赋给Context.User对象.这里需要用到HttpModule, 你可以自己写一个HttpModule,也可以用默认的Global.asax. 在这里我们采用Global.asax.在AuthenticateRequest事件中完成我们的逻辑处理.
public void Global_AuthenticateRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app.Context.User != null)
{
if (app.Context.User.Identity.IsAuthenticated)
{
app.Context.User = new myUser(app.Context.User.Identity.AuthenticationType, app.Context.User.Identity.IsAuthenticated, app.Context.User.Identity.Name);
}
}
}
这样在页面中就可以取登录用户的QQ号码了.
{
HttpApplication app = sender as HttpApplication;
if (app.Context.User != null)
{
if (app.Context.User.Identity.IsAuthenticated)
{
app.Context.User = new myUser(app.Context.User.Identity.AuthenticationType, app.Context.User.Identity.IsAuthenticated, app.Context.User.Identity.Name);
}
}
}
string qqCode=((myUser)Page.User).QQ;