代码之家  ›  专栏  ›  技术社区  ›  kamens

<machinekey decryptionkey=“autogenerate”…被IIS忽略。不会使上一个会话的cookie失效

  •  8
  • kamens  · 技术社区  · 15 年前

    (请参阅下面的问题了解更多上下文):

    在什么情况下

    <machineKey
          validationKey="AutoGenerate,IsolateApps"
          decryptionKey="AutoGenerate,IsolateApps"/>
    

    在web.config中,是否无法自动生成新的machinekey-on-app池回收?这就是我看到的行为…


    我正在MVC应用程序中使用标准的ASP.NET FormsAuthentication。如果我使用 FormsAuthentication.GetAuthCookie 并且不要使用持久cookie(依赖浏览器的会话来记住我的授权状态),我希望回收IIS应用程序池会使会话对该cookie的了解失效……从而注销所有没有持久cookie的用户。

    这在我的一个IIS安装(xp)上发生,但在另一个IIS配置(服务器2K3)上,FormsAuthentication cookie(以标准名称“.aspxauth”)仍然有效,并继续授权用户。

    是否有人知道发生这种情况的原因或是什么配置控制了这种行为?

    显然,回收应用程序池无法控制浏览器是否仍发送.aspxauth cookie(只要我没有关闭浏览器,cookie还没有过期)。

    如果IIS安装在回收后正确拒绝身份验证,我可以看到传入的cookie Request.Cookies 期间 Application_BeginRequest 事件…但一旦控件移动到global.asax.cs中的下一个可用事件 (Application_AuthenticateRequest ,cookie已从 请求饼干 收集 .

    为什么这两种IIS/ASP.NET配置都没有发生?


    如果这不清楚,形成问题的一个简单方法是:

    为什么 HttpContext.Current.Request.Cookies[".ASPXAUTH"] 从变化 {System.Web.HttpCookie} 当我单步执行单个请求时,从 应用程序开始请求 Application_AuthenticateRequest ?


    更多调试信息:

    如果我将以下代码附加到global.asax.cs的FormsAuthentication ouOnAuthenticate事件…

    var cookie = Request.Cookies[FormsAuthentication.FormsCookieName];
    if (cookie != null)
    {
        var val = cookie.Value;
        try
        {
            FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(val);
        }
        catch (Exception)
        {
        }
    }
    

    …然后在请求期间 之前 我回收IIS应用程序池,不会捕获任何异常。回收IIS应用程序池后,当从浏览器发送完全相同的.aspxauth cookie时,将捕获加密异常(“填充无效,无法删除。”)

    为什么会这样?

    2 回复  |  直到 6 年前
        1
  •  -2
  •   John Saunders Tony    15 年前

    表单身份验证cookie与会话状态无关。

        2
  •  3
  •   r3mark    6 年前

    我们的应用程序是无状态的(不需要会话),但是我们遇到了这样一种情况:应用程序池回收导致服务器环境中所有machinekey加密的cookie无效(上述问题)。这是因为 每一次循环都会改变机器键,但事实并非如此。 .

    autogenerate修饰符指定ASP.NET生成随机键并 商店 当地安全机构(LSA)的IT

    https://msdn.microsoft.com/en-us/library/w8h3skw9%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

    “本地安全机构(LSA)”是指分配给应用程序池的用户,请参阅下面的详细信息,因为这是问题所在。

    问题在于我们使用的是专用用户帐户 为了运行应用程序池,并简单地创建用户,然后将其分配给应用程序池,似乎不会触发创建注册表部分,然后在其中存储机器密钥。您可以通过检查注册表自己验证这一点。

    1. hklm/software/microsoft/windows nt/currentversion/profilelist(用于获取刚创建的用户的SID;如果该用户不在,则这已经是一个错误的符号)
    2. hku/[usersidfrombefore]/software/microsoft/asp.net/…(机器钥匙应存放在那里)

    解决方案是在计算机上以该用户的身份登录 (普通的Windows登录屏幕)以便创建相关的注册表部分。不过,可能有更快或更微妙的方法来建立注册表部分。