我的问题是新的 simplemembership 提供程序在第一次尝试时失败了一个好的用户名/密码组合。第一次失败的尝试产生现在包含用户名的 .ASPXAUTH,第二次尝试将使用相同的数据。
我知道这与 .ASPXAUTH cookie b/c 绑定,如果我在第一次(失败)尝试后删除它,那么我会得到相同的结果。最终结果是,除非它在 auth cookie 中有一个与传入的表单用户名匹配的用户名,否则该人需要第二次登录。这与连接数据库或初始化连接 b/c 无关,我每次都可以重现此行为。
想法?
[HttpPost]
[AllowAnonymous]
//[ValidateAntiForgeryToken]
[HandleError(View = "AntiForgeryExceptionView", ExceptionType = typeof (HttpAntiForgeryException))]
public ActionResult Login(LoginModel model, string returnUrl)
{
ViewBag.Message = "Login";
if (ModelState.IsValid && WebSecurity.UserExists(model.UserName))
{
WebSecurity.Login(model.UserName, model.Password, model.RememberMe);
if (WebSecurity.CurrentUserId > 0)
{
if (!IsRegistered(WebSecurity.CurrentUserId))
{
ModelState.AddModelError("", "You cannot log in before registering.");
return View(model);
}
if (HttpContext.Session != null)
{
Helpers.MemberService.Set(new MemberSession
{
UserId = WebSecurity.CurrentUserId,
SessionId = HttpContext.Session.SessionID
});
}
var cookie = new HttpCookie("MemberId")
{
Expires = DateTime.Now.AddDays(-1) // or any other time in the past
};
HttpContext.Response.Cookies.Set(cookie);
HttpContext.Response.Cookies.Add(new HttpCookie("UserId", WebSecurity.CurrentUserId.ToString(CultureInfo.InvariantCulture)));
if (string.IsNullOrEmpty(returnUrl))
{
// we can assume the user has just logged on...
returnUrl = "../Summary.htm";
}
return RedirectToAction(returnUrl);
}
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
<sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core">
<section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
<section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
<section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" />
<section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth.OpenId" requirePermission="false" allowLocation="true" />
</sectionGroup>
</configSections>
<appSettings configSource="Helpers\Config\appsettings.config" />
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
<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.Optimization" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
<trust level="Full" />
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="StructureMap" publicKeyToken="e60ad81abae3c223" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.4.0" newVersion="2.6.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="DotNetOpenAuth.AspNet" publicKeyToken="2780ccd10d57b246" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="DotNetOpenAuth.Core" publicKeyToken="2780ccd10d57b246" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
</dependentAssembly>
</assemblyBinding>
<legacyHMACWarning enabled="0" />
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
<system.net>
<defaultProxy enabled="true" />
<settings>
<!-- This setting causes .NET to check certificate revocation lists (CRL)
before trusting HTTPS certificates. But this setting tends to not
be allowed in shared hosting environments. -->
<!--<servicePointManager checkCertificateRevocationList="true"/>-->
</settings>
</system.net>
<dotNetOpenAuth>
<messaging>
<untrustedWebRequest>
<whitelistHosts>
<!-- Uncomment to enable communication with localhost (should generally not activate in production!) -->
<!--<add name="localhost" />-->
</whitelistHosts>
</untrustedWebRequest>
</messaging>
<!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
<reporting enabled="true" />
<openid>
<relyingParty>
<security requireSsl="false">
<!-- Uncomment the trustedProviders tag if your relying party should only accept positive assertions from a closed set of OpenID Providers. -->
<!--<trustedProviders rejectAssertionsFromUntrustedProviders="true">
<add endpoint="https://www.google.com/accounts/o8/ud" />
</trustedProviders>-->
</security>
<behaviors>
<!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
with OPs that use Attribute Exchange (in various formats). -->
<add type="DotNetOpenAuth.OpenId.RelyingParty.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth.OpenId.RelyingParty" />
</behaviors>
</relyingParty>
</openid>
</dotNetOpenAuth>
<uri>
<!-- See an error due to this section? When targeting .NET 3.5, please add the following line to your <configSections> at the top of this file:
<section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
-->
<!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
which is necessary for OpenID urls with unicode characters in the domain/host name.
It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
<idn enabled="All" />
<iriParsing enabled="true" />
</uri>
<log4net>
<appender name="GeneralLog" type="log4net.Appender.RollingFileAppender">
<!--<file value="${TEMP}\\Logs\\AppName_${COMPUTERNAME} " />-->
<file value="Logs\\WebLog.log" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<staticLogFileName value="false" />
<datePattern value=".yyyyMMdd.'log'" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="5MB" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n" />
</layout>
</appender>
<appender name="DebugAppender" type="log4net.Appender.DebugAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="GeneralLog" />
<appender-ref ref="DebugAppender" />
</root>
</log4net>
</configuration>