登录用户会在一段时间后退出

时间:2012-03-16 00:54:13

标签: c# asp.net-mvc-3 sql-server-2008 session web-config

我制作了一个新的MVC3应用程序,它托管在WinHost的基本计划中。

问题的关键是,达到了应用程序池内存限制,并且每个会话InProc都被删除,这意味着我的用户已经注销。

根据他们的文档,我看到了:

http://support.winhost.com/KB/a626/how-to-enable-aspnet-sql-server-session-on-your-web.aspx

按照上面列出的步骤后,这是我的web.config的内容:

<?xml version="1.0"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=152368
  -->
<configuration>  
  <connectionStrings>    
    <!-- REMOVED FOR PRIVACY -->
  </connectionStrings>
  <appSettings>
    <add key="webpages:Version" value="1.0.0.0"/>
    <add key="ClientValidationEnabled" value="true"/>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
  </appSettings>
  <system.web>    
    <sessionState mode="SQLServer"
                  allowCustomSqlDatabase="true"                  
                  cookieless="false"
                  timeout="2880"
                  sqlConnectionString="data Source='tcp:s407.winhost.com';database='DB_41_xx';user id='DB_11_xx_user'; password='xx';" />
    <trust level="Full"/>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </assemblies>
    </compilation>
    <authentication mode="Forms">
      <forms loginUrl="~/" timeout="2880"/>
    </authentication>
    <membership>
      <providers>
        <clear/>
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/"/>
      </providers>
    </membership>
    <profile>
      <providers>
        <clear/>
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
      </providers>
    </profile>
    <roleManager enabled="false">
      <providers>
        <clear/>
        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/"/>
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/"/>
      </providers>
    </roleManager>
    <pages>
      <namespaces>
        <add namespace="System.Web.Helpers"/>
        <add namespace="System.Web.Mvc"/>
        <add namespace="System.Web.Mvc.Ajax"/>
        <add namespace="System.Web.Mvc.Html"/>
        <add namespace="System.Web.Routing"/>
        <add namespace="System.Web.WebPages"/>
      </namespaces>
    </pages>
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-4.0.8.0" newVersion="4.0.8.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

问题在于:

我的用户在一段时间后仍然会被记录。我认为在会话中使用SQL可以防止这个问题。

以下是关于我如何登录用户的相关代码:

[HttpPost]
public ActionResult Login(LogOnModel model)
{
    using (EfAccountRepository accountRepository = new EfAccountRepository())
    {
        if (accountRepository.ValidateCredentials(model.Email, model.Password))
        {
            FormsAuthentication.SetAuthCookie(model.Email, true);
            return RedirectToAction("Index", "Home");
        }    
    }

    ModelState.AddModelError("", "Your email or password is incorrect.");
    return View(model);
}

以下是我用来查看用户是否已登录的一些代码:

    public static MvcHtmlString AdminDashboardLink()
    {
        if (SecurityHelpers.UserIsPartOfCompany(HttpContext.Current))
        {
            string html = "<li><a href='/Admin'>ADMIN DASHBOARD</a></li>";
            return new MvcHtmlString(html);
        }
        else
        {
            return new MvcHtmlString("");
        }
    }

    public static bool UserIsPartOfCompany(HttpContext context)
    {
        if (!context.Request.IsAuthenticated)
            return false;

        using (EfAccountRepository accountRepository = new EfAccountRepository())
        {
            var loggedInUser = accountRepository.FindByEmail(context.User.Identity.Name);
            string[] userRoles = accountRepository.GetRolesForUser(loggedInUser.AccountId);

            return userRoles.Contains("Editor") || userRoles.Contains("Finance") || userRoles.Contains("Administrator");
        }            
    }

有什么建议吗?也许我的web.config很拙劣,这导致了问题。也许在添加会话信息后我还需要删除一些内容?

2 个答案:

答案 0 :(得分:4)

由于垃圾收集器会清除分配给您的应用程序的计算机密钥并分配一个新密钥,导致用户退出登录,因此会导致这种情况。解决方案是为您的应用程序生成machineKey并将其放在system.web下的web.config中,如

<system.web>
    <machineKey validationKey="###YOUR KEY HERE ###"
                decryptionKey="## decrypt key here ##" 
                validation="SHA1" decryption="AES" />
...
...

此链接可以帮助您http://aspnetresources.com/tools/machineKey

答案 1 :(得分:-1)

表单auth与会话无关。它与会话状态无关。所需的一切都存储在表单auth cookie中。

你的超时时间设置为2880,所以48小时即两天,所以我预计会发生超时。

相关问题