读书人

使用Forms验证的时候如果客户端禁用

发布时间: 2012-05-13 16:39:43 作者: rapoo

使用Forms验证的时候,如果客户端禁用了cookie该怎么办?
花了一天时间了。最后这个问题还是没有解决,网上搜了一把,还是无功而返。。。

算了,请教一下大牛们,先谢啦!

先贴一段代码吧,算是记录一下。

C# code
    protected void btnLogin_Click(object sender, EventArgs e)    {        userName = txtUserName.Text.Trim();        pwd = txtPwd.Text.Trim();        if (userName == "xzl" && pwd == "123")         {            ////方式一:授权并且自动跳转。            //FormsAuthentication.RedirectFromLoginPage(userName, false);//将经过身份验证的用户重定向回“最初请求的 URL 或默认 URL”。            ////方式二:授权,自由控制跳转。            //FormsAuthentication.SetAuthCookie(userName, false);//发放凭证            //Response.Redirect("Default.aspx");            ////方式三(1):自定义授权,自由控制转向。(方式三1中,效果和方式一、二中差不多)            //创建加密的 Forms 身份验证票证的 FormsAuthenticationTicket 对象。            //FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddHours(1), false, "userDate", FormsAuthentication.FormsCookiePath);            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(userName, false, 300);            //根据“加密的 Forms 身份验证票证的 FormsAuthenticationTicket 对象”生成一个字符串,该字符串存放客服端cookie中。            string encTicket = FormsAuthentication.Encrypt(ticket);            string cookieAuthKey = FormsAuthentication.FormsCookieName;//获取cookie中的key值,该值根据配置文件<forms loginUrl="Login.aspx" name=".ASPXFORMSAUTH"></forms>中的“name”属性确定。            HttpCookie cookie = new HttpCookie(cookieAuthKey, encTicket);            cookie.Expires = DateTime.Now.AddDays(3);//设置cookie过期时间            Response.Cookies.Add(cookie);//发放凭证            string redirectUrlOld = FormsAuthentication.GetRedirectUrl(userName, false);//返回导致重定向到登录页的“原始请求的重定向 URL”。            Response.Redirect(redirectUrlOld);//重定向到原始页面            //“登录页”根据配置文件<forms loginUrl="Login.aspx" name=".ASPXFORMSAUTH"></forms>中的loginUrl确定。            //string loginUrl = FormsAuthentication.LoginUrl;//获取“登录页”。            //FormsAuthentication.RedirectToLoginPage();//定向到“登录页”。            ////方式三(2):            //HttpCookie coo = FormsAuthentication.GetAuthCookie(userName,false);            //Response.Cookies.Add(coo);            //Response.Redirect("Default.aspx");            return;        }        Response.Write("用户名或密码错误!");    }



问题来了:
1、使用Forms验证的时候,如果客户端禁用了cookie该怎么办?
2、服务器端的验证票存储在什么“地方”,就像sessionid一样,有好几种存储方式,那么存储的这个“验证票证”会不会不稳定呢?

[解决办法]
1,禁用cookie你可以进行提示,或者采用<sessionState cookieless="true" />这样的方法存储到url里面。

2,服务器端不进行保存的,都是cookie传递的,然后服务器端解密
[解决办法]
会将身份验证标记保留在 Cookie 或页的 URL 中。
当web.config配置文件中 Mode 设置为 Forms的时候,会经过FormsAuthenticationModule,FormsAuthenticationModule 继承IHttpModule.
会获取cookie并解密重新获取到验证票,然后设置用户标识HttpContext.User
[解决办法]
<authentication mode="Windows">
<forms
name=".ASPXAUTH"
loginUrl="login.aspx"
defaultUrl="default.aspx"
protection="All"
timeout="30"
path="/"
requireSSL="false"
slidingExpiration="true"
cookieless="UseDeviceProfile" domain="" 研究一下这个
enableCrossAppRedirects="false">
<credentials passwordFormat="SHA1" />
</forms>
<passport redirectUrl="internal" />
</authentication>


------解决方案--------------------


为了更好的浏览效果
请开启cookies

其实会关闭cookies的人 应该都知道cookies是干什么用的
浏览器默认都是开启的
既然他那么蛋疼就继续让他蛋疼好了
[解决办法]
当启用 cookieless="UseUri"时,cookie保存到url中,而你Response.Redirect直接跳转url中没有带cookie信息,导致验证失败,将在跳回login页面
而FormsAuthentication.RedirectFromLoginPage跳转时会验证cookieMode模式
,CookiesSupported 判断CookieMode模式,当是useUri时返回true,其余这边不详细说明。最后Response.Redirect(returnUrl, false);跳转到目标页。

C# code
public static void RedirectFromLoginPage(string userName, bool createPersistentCookie, string strCookiePath){    Initialize();    if (userName != null)    {        HttpContext current = HttpContext.Current;        string returnUrl = GetReturnUrl(true);        if (CookiesSupported || IsPathWithinAppRoot(current, returnUrl))        {            SetAuthCookie(userName, createPersistentCookie, strCookiePath);            returnUrl = RemoveQueryStringVariableFromUrl(returnUrl, FormsCookieName);            if (!CookiesSupported)            {                int index = returnUrl.IndexOf("://", StringComparison.Ordinal);                if (index > 0)                {                    index = returnUrl.IndexOf('/', index + 3);                    if (index > 0)                    {                        returnUrl = returnUrl.Substring(index);                    }                }            }        }     else{         //...     }
[解决办法]
你不太可能去因为个别人而去设置“cookieless”,就好像一个百货商场不可能因为个别人不喜欢没有她想买的货物于是就干脆把商场关门或者只卖这个别人喜欢的货物一样。

我同意#9后半段所说的,特意去关闭cookie的人都知道自己再干什么。或者它就是被某些自称为“杀流氓”的流氓软件(某些号称是杀毒软件的东西)给杀掉了。

你还可以考虑RIA,例如silverlgiht可以在客户端保存数据库,而不是cookie那一点东西。
[解决办法]
就算你用URL实现
http://localhost:4436/WebSite1/(F(Acmju2IimC-rVwnrJbRQRHY5NZ6D1rzTKYGk6apbzt1GQxbnjWEJZsY-TDHzDbRc2U_2PVuMPkfTQ4pL3vFHfsFLO7akx91_bpNNzfmkI5E1))/Admin/Default.aspx
难道你没有发现这URL超级不友好

另外是否有考虑过SEO 这么不友好的链接 会不会被降分
google baidu 不收录了
后果你知道的

另外如果客户端关闭了JS 你怎么实现ajax

读书人网 >asp.net

热点推荐