哥最近准备把网站的登录模块重写,采用ASP.NET自带的Forms验证方式。一直觉得微软的登录肯定要比自己写程序判断Session神马的要完善。
我的场景是这样的:
一个普通的网站,分为前台和后台。前台是给Internet访客看的,无需登录。后台是给管理员发表文章和管理网站的,要求登录才能访问。
这样的网站我们通常这样设计目录结构:
Web -----网站根目录
{
Console ----- 后台管理入口
{
Default.aspx ----- 登录页(一般叫做Login.aspx)
Welcome.aspx ----- 欢迎页(登录成功就跳转到此页)
….aspx -----各种后台页面
}
Default.aspx ----- 网站首页(无需登录就能看)
…..aspx -----各种网站内容页面(也是无需登录就能看)
}
这个例子中我们要求只有Console下的页面才需要登录。这是肿么做的呢?
先来看看最简单的Forms验证:
一、在web.config的system.web节点下加入下面的代码
<authentication mode="Forms"> <forms loginUrl="Console/Default.aspx" name=".ASPXFORMSAUTH" defaultUrl="Console/Welcome.aspx"> </forms> </authentication> <authorization> <deny users="?"/> </authorization>
二、登录页面Default.aspx和欢迎页面Welcome.aspx的代码
这个与本文讨论内容无关,大家自己看一下MSDN的例子:http://msdn.microsoft.com/zh-cn/library/xdt4thhy%28v=VS.80%29.aspx
配置完这些,我们访问网站中的任意页面,都会要求登录了。可是在我们的需求里,我们希望只有Console下的页面才需要登录访问,怎么写呢?
我一开始的想法是在Console目录下建个web.config,并把关于验证的authentication和authorization节点都放在Console/web.config的system.web下。后来发现这样做会引起运行时错误:
It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.
无奈,查MSDN也没查出个P来。经过一番开荒摸索,我终于找到了最简单的解决办法:
一、把Web根目录下的web.config中allow users的属性值设为“*”,意思是允许任意用户访问根目录下的所有页面。
<authentication mode="Forms"> <forms loginUrl="Console/Default.aspx" name=".ASPXFORMSAUTH" defaultUrl="Console/Welcome.aspx"> </forms> </authentication> <authorization> <allow users="*"/> </authorization>
二、在Console下再建个web.config,这个文件的作用域只是Console目录下的所有页面
Console\Web.config文件全部代码:
<?xml version="1.0"?> <configuration> <system.web> <authorization> <deny users="?"/> </authorization> </system.web> </configuration>
最终的目录结构:
现在再访问Web\Default.aspx就不需要登录了:
如果访问Console\Welcome.aspx就会被强制要求登录:
登录之后就可以看Welcome.aspx了:
总结:
以下是我自己的理解,可能会坑爹,大家自己凑合着看吧:
1. authentication节点只能在网站根目录的web.config中定义一次。
2. 让Web\Console\Web.Config下的allow users="?" 覆盖掉 Web\Web.Config下的allow users="*"