我在。net2.0的环境下是这样实现的,
我是这样写的:
//这里的 strUserPassport 是序列化以后的用户通行证,他是一个对象
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(2, passport.user_id, DateTime.Now, DateTime.Now.AddMinutes(30), true, strUserPassport, "/"); //建立身份验证票对象 
string HashTicket = FormsAuthentication.Encrypt(Ticket); //加密序列化验证票为字符串
//写.net Form认证所需要的Cookie
HttpCookie FormCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket);FormCookie.HttpOnly = true;
FormCookie.Path = FormsAuthentication.FormsCookiePath;
FormCookie.Expires = Ticket.Expiration;
Context.Response.Cookies.Add(FormCookie);
问题一:如果我不写这句话
FormsAuthentication.SetAuthCookie(passport.user_id,true); 那么系统就会自动的让我重新登录,在。net1.0中不会这样我是这样读的:System.Web.Security.FormsIdentity Id1 = (System.Web.Security.FormsIdentity)this.Context.User.Identity;
FormsAuthenticationTicket Ticket1 = Id1.Ticket; //取得身份验证票
string strPassport = Ticket1.UserData;//得到将身份验证票中的序列化数据但是每次总是报这个错误
无法将类型为“System.Security.Principal.GenericIdentity”的对象强制转换为类型“System.Web.Security.FormsIdentity”。请问各位高手有没有办法帮我解决,或者给一个例子急!!!在线等待!!!

解决方案 »

  1.   

    baidu一下你的这个错误,另外,web.config配置好了吗?~~
      

  2.   

    我晕,看错了,以为是asp.net~~
      

  3.   

    配置文件因该都是对的,如下,
    <authentication mode="Forms">
    <forms name="PORTAL" loginUrl="page/login.aspx" timeout="30" path="/" ></forms>
    </authentication>不知怎么搞得,就是不能通过,在windows 日志里有提示,forms认证失败
      

  4.   

    看上去都没问题,问题1在2.0中也不会出现,看看是不是你测试的哪个页面有其他代码影响了,然后就是web.config中的<location配置的有没有问题!!!
      

  5.   

    System.Web.Security.FormsIdentity Id1 = (System.Web.Security.FormsIdentity)this.Context.User.Identity;
    FormsAuthenticationTicket Ticket1 = Id1.Ticket; //取得身份验证票
    string strPassport = Ticket1.UserData;//得到将身份验证票中的序列化数据但是每次总是报这个错误
    无法将类型为“System.Security.Principal.GenericIdentity”的对象强制转换为类型“System.Web.Security.FormsIdentity”。
    ======================================================System.Security.Principal.GenericIdentity和System.Web.Security.FormsIdentity分属两个完全不同的类。他们不是继承于同一个接口,所以无法转化。FormsIdentity是用来构建User.Identity(GenericIdentity类),但是不可逆转。下面要讨论如何读取。首先,要从你的HttpCookie里面把string读出来,然后,用FormsAuthentication.Decrypt来重建你要的HashTicket
      

  6.   

    HttpCookie FormCookie = FormsAuthentication.GetAuthCookie(User.Name, true);
    FormsAuthenticationTicket Ticket = FormsAuthentication.Decrypt(FormCookie.Value);上面第一个问题,如果前面不用SetAuthCookie的话,后面你也无法使用GetAuthCookie来获得这个认证的Cookie。
      

  7.   

    在 。net2.0里SetAuthCookie 的源码里其实是调用 GetAuthCookie 方法生成Form认证Cookies的,GetAuthCookie方法 并不会得到以前存储的Cookies,所以你先
    FormsAuthentication.SetAuthCookie(passport.user_id,true); 然后 再GetAuthCookie 是错误的,这样会生成两个Cookie而且名字一样
      

  8.   

    我现在的情况是这样的,有一个权限门户网站 Portal 它对用户进行认证,认证完毕后通过链接,让Portal网站里的一个Iframe跳转到一个应用网站,在跳转的同时会传递一个token过去,应用网站会接受这个token然后调用portal的 WebService,以token为参数进行再次的认证,这样就实现了借助webservice进行跨网站的认证,认证完毕后webservice会返回一个对象,这个对象存储了所有的认证信息,我会在应用网站里将这个信息序列化,并且存储到form cookie里  问题就出在存储formcookie 这个环节,存进去了取的时候 form cookie是存在的 但是 form ticket 的 userData确是空的,但是我明明存储了的FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(2, passport.user_id, DateTime.Now, DateTime.Now.AddMinutes(new Com.Sysnet.ChinaLife.Portal.DBO.SystemConfigValues().SAVE_FORM_COOKIES_TIME), true, strUserPassport, FormsAuthentication.FormsCookiePath); //建立身份验证票对象 
    string HashTicket = FormsAuthentication.Encrypt(Ticket); //加密序列化验证票为字符串
    //写.net Form认证所需要的Cookie
    HttpCookie FormCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket);
    FormCookie.HttpOnly = true;
    FormCookie.Path = FormsAuthentication.FormsCookiePath;
    FormCookie.Expires = Ticket.Expiration;
    FormCookie.Secure = FormsAuthentication.RequireSSL;
    Response.Cookies.Add(FormCookie);
    结果 到另一个页面就提示 没有认证,自动跳转到login页面了 并且cookie值得不到
    是不是因为有个iframe 所以才会出现这个问题
      

  9.   

    请问各位高手,这种包含iframe的跨网站的form认证怎么整,急!!!
      

  10.   

    在 。net2.0里SetAuthCookie 的源码里其实是调用 GetAuthCookie 方法生成Form认证Cookies的,GetAuthCookie方法 并不会得到以前存储的Cookies,所以你先
    FormsAuthentication.SetAuthCookie(passport.user_id,true); 然后 再GetAuthCookie 是错误的,这样会生成两个Cookie而且名字一样
    ======================================================================汗,犯了概念性错误,理解不够深刻,知识还待加强。
    LZ要做的是跨站点的认证。需知道,Cookie这东西,因为Domain不同,在跳转Domain之后,就无法读取了。而浏览的网址不同,就意味着Domain不同。流程似乎是这样:用户输入用户名和密码是在Domian A,然后跳转到了Domain B,这时候Domain B来读取Cookie,因为Cookie写的是Domain A,所以Domian B读不到。鉴于如此,想了一个办法,可以试试看。不知道你有多少个网站需要认证的。比如3个网站ABC。
    你要同时把Login.aspx和AddAuthCookie.aspx这两个页面放到ABC三个网站下。用户如果在A认证,A认证通过以后,转到A的AddAuthCookie.aspx加入认证的票据,然后A会把加密的TicketString传给B的AddAuthCookie.aspx,然后B传给C,C又回到A的Login.aspx,流程如下
    From: http://www.a.com/login.aspx
    Redirect: http://www.a.com/AddAuthCookie.aspx; http://www.b.com/AddAuthCookie.aspx; http://www.c.com/AddAuthCookie.aspx;
    TicketString: xxxxxx
    每一个AddAuthCookie.aspx的页面,都先根据传过来的TicketString,建立一个AuthCookie,然后把第一个Redirect读出,更改Redirect string,然后Redirect到下一个AddAuthCookie页面,如果没有下一个页面了,就Redirct回From的页面。
      

  11.   

    或者你试试看在使用Response.Cookie.Add的时候,将FormCookie.Domain这个属性改一下。比如要跳转到B,就用B的Domain。然后再次Response.Cookie.Add,把Domain B的验证Cookie写进去。
      

  12.   

    一、情况其实是这样的,我的两个网站是采用各个独立的form认证,
    1、我有一个权限门户A,A系统可以独立运行;
    2、还有n个应用系统;
    3、A对用户认证后会生成一个token这个token是自己用程序加密的,跟form认证无关;
    二、认证过程是这样的:
    1、门户系统中会有许多链接,链接到各个应用系统
    2、在链接到应用系统的同时,门户A会生成token,传递给应用系统的认证页面AppFuncLink.aspx(这个认证页面就是应用系统的web.config配置form标签里的loginUrl)
    3、应用系统的AppFuncLink.aspx页面,接受token,然后为应用系统自己生成新的formrticket
    4、portal的formt cookie名称和应用系统的form cookies名称不一样,即在配置文件中form标签里的name属性是不一样的,因此系统在存储时是两个cookie ,但是生成ticket是用的username是一样的,调用方法如下
    new FormsAuthenticationTicket(2, user_id, DateTime.Now, DateTime.Now.AddMinutes(30), false, strUserPassport, FormsAuthentication.FormsCookiePath); //建立身份验证票对象 三、问题
    1、现在的问题就在于,外围系统生成了自己的ticket后居然还是没有认证通过,系统还是系统跳转到登录页面,我在调试的时候发现,我存储完了cookie后马上调用却调用不了,userData的值是空的,是不是iframe的问题,感觉就跟没有认证一样。
    2、我现在有点困惑,。net是在哪个环节设置为认证通过的,如何判断认证通过了,哪个位高手能详细说明一下,我自己去设置认证通过得了。
      

  13.   

    FormsAuthenticationTicket t = new FormsAuthenticationTicket(2, user_id, DateTime.Now, DateTime.Now.AddMinutes(30), false, strUserPassport, FormsAuthentication.FormsCookiePath); //建立身份验证票对象
    FormsIdentity i = new FormsIdentity(t);
    string UserInRole = {"User"};
    GenericPrincipal p = new GenericPrincipal(i, UserInRole);
    HttpContext.Current.User = p; 这个是自定义登陆,试试看。
      

  14.   

    合起来写
    FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(2, passport.user_id, DateTime.Now, DateTime.Now.AddMinutes(new Com.Sysnet.ChinaLife.Portal.DBO.SystemConfigValues().SAVE_FORM_COOKIES_TIME), true, strUserPassport, FormsAuthentication.FormsCookiePath); //建立身份验证票对象 
    string HashTicket = FormsAuthentication.Encrypt(Ticket); //加密序列化验证票为字符串
    //写.net Form认证所需要的Cookie
    HttpCookie FormCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket);
    FormCookie.HttpOnly = true;
    FormCookie.Path = FormsAuthentication.FormsCookiePath;
    FormCookie.Expires = Ticket.Expiration;
    FormCookie.Secure = FormsAuthentication.RequireSSL;
    // 进行自定义认证
    FormsIdentity i = new FormsIdentity(Ticket);
    string UserInRole = {"User"};
    GenericPrincipal p = new GenericPrincipal(i, UserInRole);
    HttpContext.Current.User = p;
    // 自定义认证结束
    Response.Cookies.Add(FormCookie);
      

  15.   

    ezhuyin(碧海蓝天) ,
    我用了你上面的方法,可以存储用户信息了,当时也能取出存进去的数据了,
    但是又有新问题,就是一旦我跳转到其它页面的时候,系统又会自动跳转到这个登录页面了,
    好像到了其它页面系统就不承认认证通过一样,
    我又用 FormsAuthentication.SetAuthCookie(passport.user_id,true);写了一下验证cookie
    这时系统是承认的,但是这种方法就不能存储自定义的cookies
    难道只要是自定义的系统就不承认,我崩溃~~
    还请,各位高手和ezhuyin(碧海蓝天)帮我看看,多谢了!!!!!!
      

  16.   

    FormCookie.Expires = Ticket.Expiration;
    这个改为
    FormCookie.Expires = DateTime.Now.AddDays(1);注:认证主要是通过Ticket来进行的,和Cookie无关,Cookie只是一个Ticket的载体,如果Ticket过期,则认证失败,如果Cookie过期,当然认证也会失败。一般是通过设定Ticket的过期,而让Cookie的存在时间大于Ticket,以保证Cookie可用。
      

  17.   

    string UserInRole = {"User"};
    这句,你的系统是否使用Roles来进行权限设定的?
      

  18.   

    刚刚改了时间还是没用,
    string UserInRole = {"User"}; 这个只是象征性的设一个,我的信息都存在Ticket的userData里了
    设置string UserInRole = {"User"}完全是为了生成GenericPrincipal 
      

  19.   

    但是如果用FormsAuthentication.SetAuthCookie(passport.user_id,true);这个方法系统就不会重新登录,奇怪了,难道系统只认自己的东东,自定义的就不认????困惑,
    苍天哪,饿第个神哪,芝麻开门吧~~~~
      

  20.   

    FormsAuthenticationTicket AuthTicket = new FormsAuthenticationTicket("user", true, 600);
    FormsIdentity f = new FormsIdentity(AuthTicket);
    string[] UserInRole = { "User" };
    GenericPrincipal gp = new GenericPrincipal(f, UserInRole);
    HttpContext.Current.User = gp;
    // bool IsAuth = User.Identity.IsAuthenticated;string HashTicket = FormsAuthentication.Encrypt(AuthTicket);
    HttpCookie FormCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket);
    FormCookie.HttpOnly = true;
    FormCookie.Path = FormsAuthentication.FormsCookiePath;
    FormCookie.Expires = AuthTicket.Expiration;
    FormCookie.Secure = FormsAuthentication.RequireSSL;
    Response.Cookies.Add(FormCookie);Response.Redirect(FormsAuthentication.DefaultUrl);我试验这段代码没有问题,页面跳转以后察看User.Identity.IsAUthenticated,显示为true
    下面为Web.config配置<authentication mode="Forms">
    <forms loginUrl="~/Default2.aspx" name="MyAuthForm" defaultUrl="Test.aspx" timeout="20">
    <credentials passwordFormat="Clear">
    <user name="username" password="password"/>
    </credentials>
    </forms>
    </authentication>
      

  21.   

    你在其他页面是如何确认用户是否认证?一般我是用察看User.Identity.IsAuthenticated属性的,不知道你是如何做的。
      

  22.   

    检查FormsAuthentication.RequireSSL属性,是否为true。如果为true,就需要使用https来访问应用。如果只是认证的时候使用SSL,那么将FormCookie.Secure设定为true试试看。
      

  23.   

    奇怪我这就是不行,老是跳转,不知道是不是由于这个系统是嵌入在portal的iframe里的原因,真是疯了
      

  24.   

    不过还是很感谢楼上这位大哥,让我对forms认证有了新的认识,我再想想其它办法,我结贴了!
      

  25.   

    iframe里面的每一个frame都是单独的页面,可以单独控制,你的做法是没错,问题是跳转。按道理来说,信息应该保留才对。我再想办法测试看看。