(一)关于“权限验证”的基础知识:
通常我们注意到有这样一个现象:在某些论坛中我们可以查看别人的帖子,但是如果你点击了回复,不是跳转到Reply类似的回复页面而是跳转到了Login.aspx页面。如果您不知道ASP.NET中还存在着这么一个可以方便检测是否是匿名用户登录的功能,通常你会选择Session去记录,简略的代码往往是这样:
- 先写一个类,直接继承于System.Web.UI.Page,然后这样Coding:
Public partial class RegisterRequired : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Session[“username”]==null)
{
Response.Redirect(“Login.aspx?FromUrl=” + Request.Url.AbsoluteUri
”);
}
}
}
- 你可以在需要验证的页面让它直接继承RegisterRequired,在Login页面自己写一些方法去验证,然后直接:Response.Redirect(Request[“FromUrl”])即可。
这样做当然是毫无问题,但是需要反复指定重定向之类的功能,比较啰嗦。相对而言,微软已经抽象出了一个类,叫做FormsAuthentication,专门用于发布凭据(验证当前客户是否是匿名还是已经登录的)。该类使用Cookie进行验证。
1)首先需要在Web.config中的<system.web>节点进行配置:
<authentication Mode=”Forms”>
<forms Name=”Cookie的Name” Timeout=”60” Cookieless=”AutoDetect” slidingExpiration=”true” loginUrl=”Login.aspx” />
<authentication>
我们通常只要这样设置就可以了,现在来逐一解释以下各个主要参数的妙用:
- Name:Cookie的名字,您可以自定义。
- Timeout:指定Cookie过期的时间,超过了这段时间Cookie作废(意味着你如果点击了某个页面之后间隔Timeout的时间段,再次重定向到某个不允许匿名用户的页面,会重新回到loginUrl指定的页面要求重新登录,单位:秒)。
- Cookieless:Cookie的模式(建议使用自动检测,防止某些用户禁用了Cookie;此时,Cookie将作为字符串嵌入到当前的地址栏中去)。
- slidingExpiration:设置Cookie过期的模式:
如果是true,意味着只要用户浏览页面,Cookie的时间将自动在上一次的时间基础上再度重新开始计时(比如你定义30,那么当第29秒的时候你在登录的情况下重定向到某个页面了,此时Cookie又从0秒开始计时,到下一个30秒一次也不操作才算作废)。
如果是false,则只能在规定的秒内浏览,超过自动重定向(建议true)。
- loginUrl:如果没有Cookie(匿名用户)访问不允许匿名用户访问的页面时候,自动重定向到登录页面,强制用户登录获取Cookie。
2)在完成这些操作以后,在<system.web>节点中您还要指定哪些页面(不)允许匿名访问:
<authorization>
<allow users=”*”/>
<deny users=”?”/>
</authorization>
这种定义表示:在web.config定义的同级目录下的所有页面都必须在获取凭据(Cookie)之后才允许您访问(“*”表示任何用户,“?”表示匿名用户),不然直接重定向到登录页面。
通常情况下,一般Default.aspx页面是允许别人进行访问的(放置于web程序的根目录下,其余的根据需求放在不同的文件夹里)。如果要设置“匿名用户除了可以直接访问Default.aspx,其余什么都不可以”的情况下,这样做比较符合:
- 和Default.aspx同目录下的那个web.config中不要写(<authorization>。
- 在需要验证的文件夹中创建一个web.config,然后写上ii)的“<authorization>
”部分即可。
如果你喜欢将不同文件夹的不同页面配置全部写在根目录的那个web.config中,您可以这样做:
<location path=”页面或者是文件夹”>
<system.web>
<authorization>
<allow users=”*”/>
<deny users=”?”/>
</authorization>
</system.web>
</location>
3)完成了以上的步骤之后,您只要在某个页面(比如登录页面,发放Cookie凭据给当前用户就可以了):
if (判断登录条件)
……
FormsAuthentication.SetAuthCookie (凭据名称, 是否跨浏览器支持)
if (string.IsNullOrEmpty(Request[“ReturnUrl”]))
{
Response.Redirect (“默认页面”);
}
Response.Redirect (Request[“ReturnUrl”]);
这里解释一下:
- “凭据名称”:应该是唯一的用户非匿名的凭据名(最好是Id或者是之后所讲的MemberShip中的UserName,这样你可以直接从User.Identity.Name获取这个Id,以便后续的操作)
- “是否跨浏览器支持”:用于指定是否对于不同浏览器进程之间享用同一个Cookie。
- ReturnUrl:是某个不允许匿名用户访问的页面路径,当使用FormsAuthentication.SetAuthCookie给当前用户分发凭据的完毕之后,判断ReturnUrl是否为空(不为空直接跳转到那个页面,否则人为指定一个页面)。
当然,如果ReturnUrl肯定不为空,您直接可以这样做:
FormsAuthentication.RedirectFromLoginPage(凭据名称, 是否跨浏览器支持) 。
除了登录之外,“注销”(SignOut也是一个非常实用的功能),实际上你可以自己在页面中这样做:FormsAuthentication.SignOut();
(二)ASP.NET中的Login控件:
ASP.NET中实际上已经为你现成提供了一个成为Login的控件,这样你就不必总是去自定义登录控件了。您可以在Login_Authenticate中写验证代码:
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
//判断条件
e.Authentication = true; //必须加入,相当于是SetAuthCookie的功能,可以直接在User.Identity.Name获取UserTextBox中的Name。
Response.Redirect(…..);
}
或者你直接指定Login1的DestinationPageUrl属性,这样一旦成功登录后就自动跳转到该属性指定的页面了。
(三)ASP.NET中登出控件:
我们通常看到的登录页面往往是:如果匿名用户访问登录页面,应该出现登录的提示框(输入用户名、口令等信息),当成功登录之后该提示框出现“欢迎XXX登录”的字样,然后底下有一个按钮,允许你注销。这个我们完全可以不写任何代码,直接通过拖拽控件实现:
除了刚才讲的登录控件之外,我们还需要三个控件:LoginView、LoginStatus和LoginName。
LoginView不直接使用,它包含两个模板:AnoymousTemplate和LoggedTemplate(RoleGroupTemplate稍后在角色部分讲到)。我们通常把Login控件放在AnoymousTemplate中,在LoggedTemplate中放上一个LoginName(自动显示登录以后的名字),同时放上一个LoginStatus控件(默认LogOut状态),当用户点击之后再次成为匿名用户。