Forms身份验证不能在分布式部署中作为认证?

参照网上的一些方法,使用Forms身份验证对应用进行分布式部署,发现没有成功。

应用部署的两台内网服务器:192.168.1.19,192.168.1.87,使用Nginx做负载分配,配置完全相同;每台都可以登录运行。

  <system.web>
    <!--配置 ASP.NET 使用的安全身份验证模式,以标识传入的用户。domain=".zt-express.com" -->
    <authentication mode="Forms">
      <forms name=".GDZDAUTHENFORMS" loginUrl="~/Login.aspx" timeout="2880" defaultUrl="~/Main.aspx" path="/" protection="All" />
    </authentication>
    <machineKey validationKey="E804106B394DE7148524A5FB0E7E282F05C3BB98553931F2B3FCDC896473390205326A876AA5490050D795FA181604651878B4285475150437A73F9D705E412A" decryptionKey="9BE9F489677A8285D6A00E902857ABB2986C73534FF2A901" validation="SHA1" />
    <authorization>
      <allow users="*" />
    </authorization>
    <anonymousIdentification enabled="true" cookieName=".GDZDanonymous" />
    <httpRuntime />
    <compilation debug="true" targetFramework="4.0" />
    <pages enableSessionState="true" controlRenderingCompatibilityVersion="4.0" />
    <customErrors mode="Off" />
    <sessionState timeout="3600">
      </sessionState>
  </system.web>

以下时登录成功后的处理

        /// <summary>
        /// 创建一个票据,放在cookie中
        /// 票据中的数据经过加密,解决一下cookie的安全问题。
        /// </summary>
        /// <param name="userInfo">登录用户</param>
        /// <param name="issueDateTime">发布时间</param>
        /// <param name="experation">过期时间</param>
        /// <param name="isPersistent">持久性</param>
        public static void SetCookie(BaseUserInfo userInfo, DateTime? issueDateTime = null, DateTime? experation = null, bool isPersistent = true)
        {
            if (issueDateTime == null)
            {
                issueDateTime = DateTime.Now;
            }
            if (experation == null)
            {
                //设置COOKIE过期时间
                experation = DateTime.Now.AddHours(SystemInfo.UserLoginExperation);
            }
            BaseSystemInfo.UserInfo = userInfo;
            BaseSystemInfo.UserInfo.ServicePassword = BaseSystemInfo.ServicePassword;
            BaseSystemInfo.UserInfo.ServiceUserName = BaseSystemInfo.ServiceUserName;
            BaseSystemInfo.UserInfo.SystemCode = BaseSystemInfo.SystemCode;
            JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
            string userData = javaScriptSerializer.Serialize(BaseSystemInfo.UserInfo);
            //生成验证票据,其中包括用户名、生效时间、过期时间、是否永久保存和用户数据等。
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userInfo.NickName, (DateTime)issueDateTime, (DateTime)experation, isPersistent, userData, FormsAuthentication.FormsCookiePath);
            HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket));
            cookie.Expires = (DateTime)experation;
            HttpResponse response = HttpContext.Current.Response;
            //指定客户端脚本是否可以访问[默认为false]
            cookie.HttpOnly = true;
            //指定统一的Path,比便能通存通取
            cookie.Path = "/";
            response.AppendCookie(cookie);

            //移除一下权限缓存数据 以便重新获取缓存数据
            RemoveRedisCache(userInfo);
        }

以下是验证的代码

            //测试 HttpContext.Current.User.Identity.IsAuthenticated在分布式部署中是否有效
            Response.Write(string.Format("测试 HttpContext.Current.User.Identity.IsAuthenticated在分布式部署中是否有效IsAuthenticated:{0}", HttpContext.Current.User.Identity.IsAuthenticated));
            Response.Write("<br/>cookie输出开始=============================");
            foreach (string cookieName in Request.Cookies)
            {
                var mycookie = Request.Cookies[cookieName];
                if (mycookie != null)
                {
                    Response.Write("<br/>" + cookieName + "中含有" + mycookie.Values.Count + "个Key");
                    if (mycookie.Values.Count > 0)
                    {
                        foreach (string s in mycookie.Values)
                        {
                            Response.Write("<br/> “" + s + "”=" + mycookie[s].ToString() + ";");
                        }
                    }
                }
            }
            Response.Write("<br/>cookie输出完毕=============================");

            Response.Write("<br/>FormsCookieName=" + FormsAuthentication.FormsCookieName);
            HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie != null)
            {
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                if (authTicket != null)
                {
                    string userData = authTicket.UserData;
                    JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
                    var userInfo = javaScriptSerializer.Deserialize<BaseUserInfo>(userData);
                    Response.Write("<br/>NickName=" + userInfo.NickName);
                }
                else
                {
                    Response.Write("<br/>authTicket = null");
                }
            }
            else
            {
                Response.Write("<br/>authCookie = null");
            }
            Response.Write("<br/>ClientIpAddress = " + UserInRedis.GetCurrentIpAddress(HttpContext.Current));
            Response.Write("<br/>ServerIpAddress = " + Request.ServerVariables.Get("Local_Addr"));

部署完毕,登录系统后,访问测试页面

可以看到当前访问应用被分配到192.168.1.19上了

现在把192.168.1.19的应用停掉,再来访问测试页面

从上面可以看出,访问被分配到192.168.1.87上了,而用于认证的.GDZDAUTHENFORMS cookie没有传过来,其它的cookie传过来了。

这是什么原因呢?同样的域名应该说cookie会传到后台的啊。

参考:http://www.cnblogs.com/fish-li/archive/2012/04/15/2450571.html等文章还是没实现,服务器配置是一样的,按理说,同样的域名,访问时应该把cookie都带过去的啊。

此问题已发到msdn:https://social.msdn.microsoft.com/Forums/vstudio/zh-CN/f666f1d1-3d9e-4620-babb-1eea9302c0d9/forms?forum=295

时间: 2024-08-09 06:20:41

Forms身份验证不能在分布式部署中作为认证?的相关文章

ASP.NET中的Forms身份验证模式

Forms身份验证:通过应用程序设置的登录界面进行用户身份验证,若验证成功则调转到验证之前请求的url. 原理图: 原文地址:https://www.cnblogs.com/JDotNet/p/3451263.html

采用Asp.Net的Forms身份验证时,持久Cookie的过期时间会自动扩展

问题描述 之前没有使用Forms身份验证时,如果在登陆过程中把持久的Cookie过期时间设为半个小时,总会收到很多用户的抱怨,说登陆一会就过期了. 所以总是会把Cookie过期时间设的长一些,比如两个小时甚至一天,这样就能保证在登陆时设置一次Cookie,用户可以操作很长时间也不过期. 虽然也可以在每次用户请求页面时检查Cookie的过期时间并自动扩展,但未免过于麻烦,不如一次设大点来的简单. 偶然发现 今天在使用Forms身份验证编写<AppBox-基于ExtAspNet的企业通用管理框架>

asp.net Forms身份验证详解

在做网站的时候,都会用到用户登录的功能.对于一些敏感的资源,我们只希望被授权的用户才能够访问,这让然需要用户的身份验证.对于初学者,通常将用户登录信息存放在Session中,笔者在刚接触到asp.net的时候就是这么做的.当我将用户信息存在在Session中时,常常会遇到Session丢失导致用户无法正常访问被授权的资源,保持用户登录状态时的安全性问题,无休止的将用户导航到登录页面等莫名其妙的问题. 其实,在asp.net中,我们有更好的解决方案,那就是通过Forms身份验证,从而对用户进行授权

Forms身份验证的配置

authentication - 认证; 身份验证; 证明,鉴定; 密押; authorization - 授权,批准; 批准(或授权)的证书; <authentication mode="Forms">    <forms name=".ASPXAUTH" loginUrl="Login.aspx" protection="All" path="/" timeout="20&q

采用Asp.Net的Forms身份验证时,非持久Cookie的过期时间会自动扩展

问题描述 之前没有使用Forms身份验证时,如果在登陆过程中把HttpOnly的Cookie过期时间设为半个小时,总会收到很多用户的抱怨,说登陆一会就过期了. 所以总是会把Cookie过期时间设的长一些,比如两个小时甚至一天,这样就能保证在登陆时设置一次Cookie,用户可以操作很长时间也不过期. 虽然也可以在每次用户请求页面时检查Cookie的过期时间并自动扩展,但未免过于麻烦,不如一次设大点来的简单. 偶然发现 今天在使用Forms身份验证编写<AppBox-基于ExtAspNet的企业通用

ASP.NET Forms 身份验证

ASP.NET Forms 身份验证 在开发过程中,我们需要做的事情包括: 1. 在 web.config 中设置 Forms 身份验证相关参数.2. 创建登录页. 登录页中的操作包括: 1. 验证用户名和密码是否正确.2. 创建身份验证票证对象.3. 将身份验证票证对象加密成字符串,写入 Cookies.4. 重定向到原始请求 URL. 1. 简单演示 web.config <?xml version="1.0"?><configuration>  <s

Forms身份验证和基于Role的权限验证

Forms身份验证和基于Role的权限验证 从Membership到SimpleMembership再到ASP.NET Identity,ASP.NET每一次更换身份验证的组件,都让我更失望.Membership的唯一作用就是你可以参考它的实现,它的数据库创建和扩展方面就真的让人实在无法使用了. 当大家欢呼着让ASP.NET开发走上ASP MVC的正确道路时,身份验证组件却走的更远了:SimpleMembership除了第三方验证的参考价值,它的主键和对领域模型的入侵让它成了摆设,而ASP.NE

关于ASP.NET的“Forms身份验证”

目录结构如图如示: 如果用户没有通过身份验证则跳转到登录页面让用户登录,在配置文件的<system.web></system.web>结点下添加如下代码: <!--身份验证方式--> <authentication mode="Forms"> <forms loginUrl="~/Login.aspx" /> </authentication> <!--授权--> <autho

OpenStack 控制节点基本环境和身份验证服务的安装部署

OpenStack Networking(neutron) 需要一个控制节点(controller node).一个网络节点(networknode)以及至少一个计算节点(compute node). 一.物理环境部署 1.物理环境规划 表1.1. OpenStack环境部署 二.安装前的部署 1.1配置主机名 [email protected]:~# vim  /etc/hostname controller 1.2 配置IP地址 [email protected]:~# vim  /etc/