无法将类型为“System.Security.Principal.GenericIdentity”的对象强制转换为类型“System.Web.Security.FormsIdentity”。
这次的系统包含两个子系统,所以做了一个分角色的身份验证系统。
web.config <system.web>中设置
<authentication mode="Forms"> <!--验证方式为窗体验证--> <forms name=".ASPXAUTH" loginUrl="~/login.aspx" protection="All" timeout="60" path="/"></forms> </authentication> <authorization> <allow users="?"/> <!--根目录网页默认为所有用户都能访问--> </authorization>
外面添加
<!--设置admin目录的访问权限--> <location path="admin/Default.aspx"> <system.web> <authorization> <!--允许角色为admin的用户可以访问--> <allow roles="admin"/> <!--拒绝所有其他用户访问--> <deny users="*"/> <!--注意以上两句的次序不能变--> </authorization> </system.web> </location> <!--设置index目录的访问权限--> <location path="index/Default.aspx"> <system.web> <authorization> <!--允许角色为stu的用户可以访问--> <allow roles="stu"/> <!--拒绝所有其他用户访问--> <deny users="*"/> <!--注意以上两句的次序不能变--> </authorization> </system.web> </location>
login.aspx页面身份验证通过后
//创建一个身份验证票 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, UserName, DateTime.Now, DateTime.Now.AddMinutes(30), false, UserRole); //将身份验证票加密 string EncrTicket = FormsAuthentication.Encrypt(ticket); //创建一个Cookie HttpCookie myCookie = new HttpCookie(FormsAuthentication.FormsCookieName, EncrTicket); //将Cookie写入客户端 Response.Cookies.Add(myCookie); //跳转到初始请求页或默认页面 Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName, false));
golbal全局应用程序中添加代码
void Application_AuthenticateRequest(object sender, EventArgs e) { //判断正在请求页的用户的身份验证信息是否为空 if (HttpContext.Current.User != null) { //判断用户是否已经进行了身份验证 if (HttpContext.Current.User.Identity.IsAuthenticated) { //判断当前用户身份验证的方式是否为Forms身份验证方式 if (HttpContext.Current.User.Identity is FormsIdentity) { //获得进行了Forms身份验证的用户标识 FormsIdentity UserIdent = (FormsIdentity)(HttpContext.Current.User.Identity); //从身份验证票中获得用户数据 FormsAuthenticationTicket ticket = UserIdent.Ticket; string UserData = ticket.UserData; //string UserData = UserIdent.Ticket.UserData; //分割用户数据得到用户角色数组 string[] rolues = UserData.Split(','); //从用户标识和角色组初始化GenericPrincipal类 HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(UserIdent, rolues); } } } }
身份验证设置完成后设置页面跳转
default页面添加代码
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity; if (id.Ticket.UserData.Contains("admin")) { //跳转到访问权限不够的错误提示页面 Response.Redirect("~/admin/Default.aspx", true); } else if (id.Ticket.UserData.Contains("stu")) { Response.Redirect("~/index/Default.aspx", true); } else Response.Redirect("~/login.aspx", true);
至此整个身份验证完成。
vs上运行没有问题,发布到IIS后报错无法将类型为“System.Security.Principal.GenericIdentity”的对象强制转换为类型“System.Web.Security.FormsIdentity”。
查找资料:
1、将网站应用程序池的托管管道模式由“集成”改为“经典”
2、网站“处理程序映射”添加”.aspx“请求路径的可执行文件“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll”,或者将ISAPI中4.0的状态改为可用状态
以上网友成功解决问题的办法在我这都不行。。。。。
login.aspx,golbal.asax,default.aspx,代码调整过无数次,各种方法试过都无效。
===================================================================================================================
突发奇想将登陆ip改为 192.127.1.8080/login.aspx,。。。OK,终于不报错误界面了。
错误信息提示 无法将类型为“System.Security.Principal.GenericIdentity”的对象强制转换为类型“System.Web.Security.FormsIdentity”,身份验证出了问题,一直以为是iis对角色身份验证有什么特殊设置,但最后发现时默认文档没有设置正确。
使用“默认文档”功能页可配置默认文档的列表。如果用户访问您的网站或应用程序,但没有指定文档名),则可以配置 IIS 提供一个默认文档,如 Default.htm。IIS 将返回与目录中的文件名匹配的列表中的第一个默认文档。
我的登陆页面是login.aspx,IIS搜索返回default.aspx。default.aspx页面中有一行代码
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
(FormsIdentity)HttpContext.Current.User.Identity;中的formsIdentity表示“一个使用了forms身份验证进行了身份验证的用户标识”,192.127.1.8080请求发送跳过了身份验证界面,所以报错。
解决:在默认文档中“添加”login.aspx
(每次网站发布后都需要添加login默认文档,所以想在代码中定位到login页面去,但发现无论是在default页面进行设置跳转,还是在golbal页面添加设置,都会报错,必须添加login页面首先进行身份验证)