首页 > 解决方案 > 登录 ASP.NET 网站并刷新页面后 httpContext.Request 不包含 auth cookie

问题描述

晚上好,

我有一个在 ASP.NET 上运行的网站,登录对于 localhost 非常有效,但对于生产失败:如果用户登录并刷新页面,那么他会被强制注销。经过一些投资后,我发现这是因为 auth cookie 而发生的,它只是没有出现在 _httpContext.Request 中的 cookie 列表中(在方法 GetAuthenticatedCustomer() 中,因为缺少 auth cookie,_httpContext.Request.IsAuthenticated为 false 并且方法返回 null)。但是,我可以在浏览器中看到这个 cookie,域属性设置正确,它没有过期,即使我手动设置了过期日期,事情也不会改变。FormsAuthentication.SetAuthCookie(name, true) 的使用也无济于事。

这是我的 FormsAuthenticationService 代码的一部分:

public virtual void SignIn(Customer customer, bool createPersistentCookie)
    {
        var now = DateTime.UtcNow.ToLocalTime();

        var ticket = new FormsAuthenticationTicket(
            1 /*version*/,
            _customerSettings.UsernamesEnabled ? customer.Username : customer.Email,
            now,
            now.Add(_expirationTimeSpan),
            createPersistentCookie,
            _customerSettings.UsernamesEnabled ? customer.Username : customer.Email,
            FormsAuthentication.FormsCookiePath);

        var encryptedTicket = FormsAuthentication.Encrypt(ticket);

        var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
        cookie.HttpOnly = true;
        if (ticket.IsPersistent)
        {
            cookie.Expires = ticket.Expiration;
        }
        cookie.Secure = FormsAuthentication.RequireSSL;
        cookie.Path = FormsAuthentication.FormsCookiePath;
        if (FormsAuthentication.CookieDomain != null)
        {
            cookie.Domain = FormsAuthentication.CookieDomain;
        }

        _httpContext.Response.Cookies.Add(cookie);
        _cachedCustomer = customer;
    }

    public virtual void SignOut()
    {
        _cachedCustomer = null;
        FormsAuthentication.SignOut();
    }

    public virtual Customer GetAuthenticatedCustomer()
    {
        if (_cachedCustomer != null)
            return _cachedCustomer;

        if (_httpContext == null ||
            _httpContext.Request == null ||
            !_httpContext.Request.IsAuthenticated ||
            !(_httpContext.User.Identity is FormsIdentity))
        {
            return null;
        }

        var formsIdentity = (FormsIdentity)_httpContext.User.Identity;
        var customer = GetAuthenticatedCustomerFromTicket(formsIdentity.Ticket);
        if (customer != null && customer.Active && !customer.Deleted && customer.IsRegistered())
        {
            _cachedCustomer = customer;
        }

        return _cachedCustomer;
    }

    public virtual Customer GetAuthenticatedCustomerFromTicket(FormsAuthenticationTicket ticket)
    {
        if (ticket == null)
            throw new ArgumentNullException("ticket");

        var usernameOrEmail = ticket.UserData;

        if (String.IsNullOrWhiteSpace(usernameOrEmail))
            return null;
        var customer = _customerSettings.UsernamesEnabled
            ? _customerService.GetCustomerByUsername(usernameOrEmail)
            : _customerService.GetCustomerByEmail(usernameOrEmail);
        return customer;
    }

我注意到本地主机和生产之间的唯一区别是,在生产中 ASP.NET_SessionId cookie 也丢失了。但是,我不知道它有多重要。

生产中的饼干

本地主机上的 Cookie

我的 web.config 的一部分:

<authentication mode="Forms">
  <forms name="NOPCOMMERCE.AUTH" loginUrl="~/login" protection="All" timeout="43200" path="/" requireSSL="false" slidingExpiration="true" />
</authentication>

目标框架是 4.5。

标签: c#asp.netcookiesforms-authenticationproduction

解决方案


推荐阅读