如何整合AD验证和ASP.NET表单验证为一个网站
一般网站只能由一种验证模式:AD验证或Form验证,但事实中我们经常碰见需要整合的情况,那么我们需要设置整个网站是基于Windows身份验证的,当失败是自动转向Form验证:
IIS及应用程序的设置:
1. 将IIS设置为禁用匿名身份验证,启用windows 集成身份验证
2. 将整个网站的缺省显示页面定位主页(登陆后要显示的页面)在Web.config文件里设定将网页导向AD验证的主页面(我们暂定为WinADLogin.aspx)。
Win7 上设置方式
Win2k3 上设置方式
特别注意:由于目前整个网站配置的是Windows集成验证,如果访问的机器不在域里,不管访问任何页面,都将弹出输入凭证的对话框:
因此我们要对WinLogin.aspx页面设置Forms的授权方式 ,对该页面拒绝匿名用户访问,当匿名用户访问时将会出错,并自动转到WebLogin.aspx页面
WebLogin.aspx页面允许匿名访问;
当使用者登入网站并且提出浏览网页需求的时候,整个登陆流程如下:
Ø 当用户访问的页面时,如果已经授权,
1. 则直接访问需要的页面
Ø 如还没有授权,则
1. 首先记录用户访问的页面到Session里
2. 若IIS中的Windows整合验证成功则由WinLogin.aspx此网页来导行使用者到:原来的要求网页
3. 若IIS的整合验证失败则导向Redict401.htm网页;
4. 在Redict401.htm让使用者转向为表单验证Weblogin.aspx页面
5. 用户在这个网页上做登入认证成功之后再导向使用者到:原本的需求页面(Session里存储的页面)。
整个流程图如下:
由于当Windows身份验证失败后,IIS将自动导向IIS自定制好的错误页面Redirect401.htm,我们无法通过程序去控制,所以我们必须自定制Redirect401.htm,将这个页面导向我们自定制的Webform身份验证的页面WebLogin.aspx页面。
Win2k3 上错误页面
Win7上错误页面
我们可以直接修改401 页面,但是不建议这么做
具体处理过程如下:
1. 在Web.config里的<system.web></system.web>节点中添加<customErrors mode="On" defaultRedirect="ApplicationErroy.aspx" ></customErrors>节点,
2. 在web.config中也可以把
<error statusCode="401.1" redirect="Weblogin.aspx" />//Windows登陆失败
//<error statusCode="403" redirect="NoAccess.htm" />//访问被禁止
//<error statusCode="404" redirect="FileNotFound.htm" />//找不到页面
3. 添加Global.asax文件,找到Application_Error事件,加入以下代码:
Exception erroy = Server.GetLastError();
string err = "出错页面是:" + Request.Url.ToString() + "<br>";
err += "异常信息:" + erroy.Message + "<br>";
err += "Source:" + erroy.Source + "<br>";
err += "StackTrace:" + erroy.StackTrace + "<br>";
Server.ClearError();
Application["erroy"] = err;
4. 添加错误处理页面:ApplicationErroy.aspx 加入以下代码;
Response.Write(Application["erroy"].ToString());
参考:401错误的具体原因:
401 - 访问被拒绝。IIS 定义了许多不同的 401 错误,它们指明更为具体的错误原因。这些具体的错误代码在浏览器中显示,但不在 IIS 日志中显示:
• |
401.1 - 登录失败。 |
• |
401.2 - 服务器配置导致登录失败。 |
• |
401.3 - 由于 ACL 对资源的限制而未获得授权。 |
• |
401.4 - 筛选器授权失败。 |
• |
401.5 - ISAPI/CGI 应用程序授权失败。 |
• |
401.7 – 访问被 Web 服务器上的 URL 授权策略拒绝。这个错误代码为 IIS 6.0 所专用。 |
以上思路虽然可以实现AD 及Form混合验证,但是需要修改的地方比较多,我们可以按以下思路改善之
对于AD用户:
- 如果某个AD用户通过AD访问我们的网站,且以前我们没有该AD用户的申请记录,则我们可以开启一个权限申请的页面;
- 该用户通过权限申请页面,选择某个角色后,向其所在组织的管理员发送开启某种角色邮件
- 该用户所在的管理员收到申请后,如核准该用户的角色,则
- 该用户再次通过AD方式登录该网站时将自动获取访问页面的权限(我们只需根据该用户的AD账户在我们的系统中查看该用户的角色和权限即可)
- 但当同样的用户通过Form方式登录时 ,它则必须输入与用户的用户名和密码才能进入系统(也就是说对于AD用户,由于AD用户在我们系统中没有密码,所以如果是第一次用Form 方式登录,系统将会发送密码邮件给该用户,该用户用该密码登录系统,登录后可以修改密码)
当由于我们网站设为window验证方式:对于非域的用户将总是提示请输入域用户信息的对话框,因此我们需要在401错误页面截取,但我们可以通过配置 customErrors 实现
<!--<customErrors mode="On" defaultRedirect="GenericErrorPage.htm">-->
<customErrors mode="Off">
<error statusCode="401" redirect="/SysAdmin/Login.aspx" />
<!--
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />-->
</customErrors>