【问题标题】:SQL Server Compact 4 as membership provider in ASP.NET MVC3SQL Server Compact 4 作为 ASP.NET MVC3 中的成员资格提供程序
【发布时间】:2011-08-29 16:23:21
【问题描述】:

我创建了一个 ASP.NET MVC3 (Razor) Web 应用程序,并将成员资格提供程序替换为 MS 的通用成员资格提供程序,通过 NuGet 安装,并将 MDF 数据库替换为 SQL Server Compact 4 SDF 数据库。

这个 SDF 一切正常,我可以从 WSAT 管理用户和角色,在登录我的开发工作站时进行验证等。无论如何,我遇到了一些奇怪的行为,也许这只是其他用户遇到的问题:如一旦我将应用程序部署到生产服务器,如果我尝试使用任何用户帐户(大约有 60 个帐户)登录,我就会因密码无效错误而被拒绝。我还将 SDF 数据库下载回了我的开发机器,它适用于任何帐户。

我可以补充一点,我以编程方式从外部列表创建了所有帐户,代码如下:

MembershipUser user = Membership.GetUser(sName);
if (user != null)
{
    Membership.CreateUser(sName, sPassword, sEmail);
    AddUserToRole(sName, bIsAdmin? "administrator" : "member");
}

无论如何,他们在 WSAT 中看起来都还不错并且很活跃。

我尝试使用管理员帐户和成员帐户,但得到相同的结果。然而,数据库与我在本地成功使用的数据库相同。我还在一个页面上列出了所有用户帐户的锁定状态,以防万一,但它们看起来都很好,并且在线和本地都没有丢失。有什么提示吗?

我的配置是这样的:

...
    <connectionStrings>
        <clear />
        <add name="ApplicationServices" 
                 connectionString="Data Source=|DataDirectory|\Organizer.sdf;" 
                 providerName="System.Data.SqlServerCe.4.0" />
        <add name="DefaultConnection" 
                 connectionString="Data Source=|DataDirectory|\Organizer.sdf;" 
                 providerName="System.Data.SqlServerCe.4.0" />
    </connectionStrings>
...
<membership defaultProvider="DefaultMembershipProvider">
    <providers>
        <clear />
        <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
    </providers>
</membership>
<profile defaultProvider="DefaultProfileProvider">
    <providers>
        <clear />
        <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
    </providers>
</profile>
<roleManager enabled="true" defaultProvider="DefaultRoleProvider">
    <providers>
        <clear />
        <add connectionStringName="ApplicationServices" applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
        <add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" />
        <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
    </providers>
</roleManager>
...

更新:在一些随机尝试中,我尝试将其中一个帐户设置为清晰的密码格式,而不是默认的散列密码格式,这有效,而所有其他未更改的帐户继续显示同样的问题。所以我必须推断出哈希密码在 SqlServer Compact 和/或我的 Web 配置中不起作用。有人知道 CF4 在这方面的问题吗?

【问题讨论】:

    标签: sql-server asp.net-mvc-3 asp.net-membership


    【解决方案1】:

    对不起,我自己找到了解决方案,至少我希望这对其他新手有用:问题出在密码哈希的机器密钥上。我认为在我的开发机器和生产服务器中它是相等的,但事实并非如此。我将密钥直接放在我的 web.config 中,以便此设置覆盖机器级别的设置(如果有)。因此,将机器密钥设置为:

    <machineKey validationKey="87172C641DE5712040FA42BFEBF230DD8D62D38CBAD58D67FA427414B767C3A64393747FCD46D5CE7E03E9798DD0491EDE6EB52FF1AC3D28FD4AEA2F693CCD32" decryptionKey="58F39AA799F12FF83F230607EAE74AD228E53D5519C51121129C21A841E385FD" validation="SHA1" decryption="AES" /> 
    

    在您的 web.config 的 system.web 中。您可以从这里使用它们的 XML 代码生成键值:

    http://aspnetresources.com/tools/machineKey

    就我而言,我的所有用户帐户都已经存在,所以我不能简单地从我原来的导入列表中重新创建它们。我宁愿使用一些代码来重置他们所有的密码。为此,请记住,Membership.ChangePassword 通常会因返回 false 而失败,至少对我而言,用户被锁定的情况并非如此(我检查了这一点,因为据说这是导致失败)。因此,如果您不能简单地更改密码,请先将其重置,然后再重新设置,例如:

    MembershipUser user = Membership.GetUser(sName);
    if (user == null)
    {
        // user not found...
        continue;
    }
    
    if (user.IsLockedOut) user.UnlockUser();
    string sTemp = user.ResetPassword();
    
    bool b = user.ChangePassword(sTemp, sPassword);
    // b is false on failure
    

    我是在控制台应用程序中完成的,因此在这种情况下,请记住将相同的 system.web 部分添加到其 app.config 中,否则密码将使用其他值进行哈希处理。

    然后我重新上传了我的 SDF 和新的 web.config(密钥必须匹配!),现在它可以工作了。旁注:通常,在 VS2010 基于 SDF 的数据库中表现得很奇怪:例如即使用户名存在,Membership.GetUser() 也会返回 null。在这种情况下,我只需获得未触及 SDF 的新副本并重试。即使关闭和重新打开 VS 也可能会有所帮助。因此,在编辑之前始终保留一份 SDF 的副本...(请记住,对于控制台应用程序,它被复制到 debug/bin 目录中,这是您将要使用的)。

    感谢所有读者

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-15
      相关资源
      最近更新 更多