ASP.Net Membership.DeleteUser
В тестировании пользователь на БД, который я использовал, был большим джефом. На производстве у него есть только Execute.
Когда я позвонил,
Membership.DeleteUser(user)
В тестировании это сработало. Я пробую то же самое в производстве, и я получаю это:
Оператор DELETE конфликтует с ограничением REFERENCE "FK__aspnet_Us__UserI__37703C52". Конфликт произошел в базе данных "Тестирование", таблице "dbo.aspnet_UsersInRoles", столбце "UserId".
В моих поисках (поисках в Google) я наткнулся на эту ссылку, где чувак говорил:
Ошибка: оператор DELETE конфликтует с ограничением REFERENCE "FK__aspnet_Me__UserI__15502E78". Конфликт произошел в базе данных "YourDBName", таблице "dbo.aspnet_Membership", столбце "UserId".
Мне потребовалось некоторое время, чтобы найти решение этой проблемы для нескольких сайтов и вариантов, поскольку ошибки и возможные решения вводили в заблуждение. Оказывается, по крайней мере, в моем случае, это была проблема с разрешениями в базе данных членства. Пользователь, которого я использую для подключения, имел доступ для просмотра сведений о членстве в самой базе данных, но как часть хранимой процедуры aspnet_Users_DeleteUser он выбирает из таблицы sysobjects. У пользователя подключения к членству, очевидно, не было достаточных прав, чтобы сделать этот выбор, поэтому полное удаление не удалось.
Для меня исправлением было добавить пользователя в роль aspnet_Membership_FullAccess для базы данных участников.
Но когда я это сделал, это не сработало. У кого-нибудь есть идеи, как с этим бороться?
7 ответов
После небольшой проверки я обнаружил, что проблема заключается в следующей строке хранимой процедуры aspnet_Users_DeleteUser:
IF ((@TablesToDeleteFrom & 1) <> 0 AND
(EXISTS (SELECT name FROM sysobjects WHERE (name = N'vw_aspnet_MembershipUsers') AND (type = 'V'))))
Есть еще 3 аналогичные строки для 3 других таблиц. Проблема заключается в том, что если пользователь, выполняющий сохраненный процесс, не имеет доступа к vw_aspnet_MembershipUsers, он не появится при выборе из sysobjects. Мне любопытно знать, почему все это заявление EXISTS необходимо.
Несмотря на это, следующее обсуждение, " Доступ к системным объектам для просмотра пользовательских таблиц без доступа к пользовательским таблицам непосредственно в SQL Server Security", содержит ответ. Предоставляя "ПРОСМОТР ОПРЕДЕЛЕНИЯ" для рассматриваемых представлений, операторы EXISTS теперь будут успешными, и вам не придется предоставлять ненужные, нежелательные или чрезмерные разрешения пользователю в строке подключения вашего приложения.
У меня также была эта проблема, и она была вызвана отсутствием представлений, чтобы исправить, я просто использовал сценарий создания из другой базы данных и воссоздал все представления vw_aspnet_*.
ОК, угадай что? Я читаю это: http://forums.asp.net/t/1254087.aspx
Хорошо, через несколько минут после отправки моего сообщения я нашел решение:) Оказывается, что SELECT PERMISSION нужно было добавить для пользователя ASPNET в представлении vw_aspnet_MembershipUsers.
Но до сих пор остается загадкой, почему я не получил ошибку, связанную с отсутствием разрешения. Утверждение EXIST просто возвращало ложь.
и дал производственному пользователю разрешение SELECT и вуаля! Оно работает! Спасибо, парни!
Я считаю, что ваше ограничение 'REFERENCE' на самом деле является внешним ключом в базе данных, который существует между таблицей aspnet_Users и таблицей aspnet_UsersInRoles. Я бы подумал, что пользователь, которого вы пытаетесь, имеет свой UserId в обеих таблицах, и прежде чем вы сможете удалить его из таблицы Users, его также необходимо удалить из таблицы UsersInRoles.
Вы пытались http://msdn.microsoft.com/en-us/library/system.web.security.roleprovider.removeusersfromroles.aspx чтобы убедиться, что все роли удалены от этого пользователя? Вы также можете проверить, проверив строки этих двух таблиц в базе данных.
Если ошибка (или аналогичная) по-прежнему сохраняется после предоставления SELECT для пользователя ASP на vw_aspnet_MembershipUsers, вы можете захотеть предоставить SELECT для некоторых других vw_aspnet_???? просмотров тоже. Особенно "профиль" и "UsersInRoles". В противном случае - по некоторым причинам SP DeleteUser получает пустой результат при ВЫБОРЕ из этих представлений и отказывается сначала удалять существующие записи из них.
Я решил это, удалив строку в proc, которая проверяет вид. У меня нет никаких представлений о членстве в asp, и они мне нигде не нужны, поэтому создавать представление просто бессмысленно, просто чтобы строка кода могла возвращать true - процесс фактически не использует представление. Возможно, если вы используете больше возможностей объектов членства, вам может понадобиться представление для чего-то другого. В любом случае проверка существования представления кажется странным способом для процесса решить, есть ли в таблице aspnet_membership строка, которую нужно удалить.
IF ((@TablesToDeleteFrom & 1) <> 0
)
--AND
-- (EXISTS (SELECT name FROM sysobjects WHERE (name = N'vw_aspnet_MembershipUsers') AND (type = 'V'))))
Может быть, лучше убедиться, что пользователь, выполняющий удаление, имеет право исправлять роли ASP.NET Membership sql. В моем случае я удалял пользователя членства, у которого есть некоторые роли и свойства профиля. Метод удаления не удался, но после назначения правильных ролей sql он сработал.
ALTER ROLE [aspnet_Profile_FullAccess] ADD MEMBER [<YOUR SQL USER>]
ALTER ROLE [aspnet_Roles_FullAccess] ADD MEMBER [<YOUR SQL USER>]
Вы также можете добавить [aspnet_Personalization_FullAccess], если вы используете эту функцию.