2012-03-16 142 views
6

我做了一个新的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是拙劣的,这是导致问题。在我添加会话信息后,也许我还需要删除某些内容?

+0

运行相同的浏览器会话时,您将看到用户注销发生? – 2012-03-16 01:58:55

+0

是的,我打开Firefox,登录到网站(托管在Winhost上)。在同一个网站上玩一会儿,几分钟后(有时候几秒钟后),我就注销了。 – 2012-03-16 02:08:32

+0

当一个asp.net应用程序池回收时,这将是空/空吗? 'context.Request.IsAuthenticated'?如果是这样,这可能是导致问题的原因。如果我切换到SQL会话,我是否需要修改检查用户是否登录的方式? – 2012-03-16 02:10:32

回答

4

由于垃圾收集器清理分配给您的应用程序的机器密钥并分配导致用户注销的新密钥,因此会导致一些时间。解决方法是为应用程序生成一个machineKey,并将其放置在web.config下的System.Web像

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

这个链接可以帮助你http://aspnetresources.com/tools/machineKey

+0

谢谢你的帮助。所以我生成了我的密钥,并将其放在我的web.config中。我是否需要设置任何其他选项才能使其工作,还是只需将它放在web.config中并完成? – 2012-03-16 14:24:00

+0

不会去考虑它,但它似乎只是将此添加到web.config文件,解决了它! :)将在两个小时内确认;我仍然应该登录。 – 2012-03-16 14:42:51

+0

只是把它放在配置会做......';)' – Rafay 2012-03-16 16:23:31

-1

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

您的超时设置为2880,因此48小时即两天,所以我期望超时发生。

+0

好的,所以我在用户中登录的方式并不正确,应该可以正常工作。另一方面,我也希望发生超时 - 但目前的超时时间不会接近两天,更不用说两个小时。任何其他想法? – 2012-03-16 01:49:09

+0

我正在使用'HttpContext.Request.IsAuthenticated'来查看用户是否已登录。这是否与SQL会话很好地相同,它可以在InProc会话(默认为MVC3)上正常工作? – 2012-03-16 01:50:18

+0

实际上,您可以解密一张票并检查它(并记录它),以便更好地处理发生的事情:http://www.hanselman.com/blog/AccessingTheASPNETFormsAuthenticationTimeoutValue。aspx是否确定您的应用程序中没有其他会话检查?有些人尝试同步(或假设他们是同步,他们不是)会话并形成auth超时,但他们不会保持彼此同步。如果你的应用程序的其他地方有代码重定向到登录,如果会话为空,这可能是你的问题的另一个来源。 – 2012-03-16 03:05:42