SQL Server Compact 4 в качестве поставщика членства в ASP.NET MVC3 - PullRequest
1 голос
/ 29 августа 2011

Я создал веб-приложение ASP.NET MVC3 (Razor) и заменил поставщика членства универсальным поставщиком членства 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 и / или моей веб-конфигурацией.Кто-нибудь знает о проблемах в этой области с CF4?

1 Ответ

2 голосов
/ 30 августа 2011

Извините, что беспокою, я нашел решение сам, по крайней мере, я надеюсь, что это может быть полезно для других новичков: проблема была в ключе машины для хеширования пароля. Я предполагал, что это было одинаково на моей машине разработчика и на моем производственном сервере, но это было не так. Я поместил ключ прямо в мой файл web.config, чтобы этот параметр перекрывал машинный уровень, если он есть. Таким образом, установите машинный ключ как:

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

в system.web вашего web.config. Вы можете сгенерировать значения ключей с помощью их 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 (ключи должны совпадать!), И теперь он работает. Примечание: часто базы данных на базе SDF VS2010 ведут себя странно: например, Membership.GetUser () возвращает значение NULL, даже если имя пользователя есть. В этом случае я просто получаю новую копию нетронутого SDF и пытаюсь снова. Даже закрытие и повторное открытие VS может помочь. Поэтому всегда сохраняйте копию своего SDF перед редактированием ... (и помните, что для консольных приложений он копируется в каталог debug / bin, это то, что вы собираетесь использовать).

Спасибо всем читателям в любом случае

...