ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: В соответствии с обменом в комментариях, в котором я делаю полный осколок себя, было получено почти из коробки решение, и этот ответ был очищен от всех недоразумений, и теперь содержит только проверенный сценарий, который может или не может решить проблему OP. ;-)
Благодарность Томасу за то, что он хладнокровен и не сдается.
Z- скажи мне, если я тебя понимаю:
Вам нужен централизованный поставщик членства для всех приложений / проектов и отдельное хранилище ролей для каждого приложения / проекта?
Возможно, вам не нужно внедрять пользовательских провайдеров. Стандартный стек может быть достаточен с незначительной модификацией хранимой процедуры . Всегда лучше постараться и сладко побеседовать с запеченными системами, чтобы делать то, что вы хотите. Это приводит к меньшему количеству работы и большему количеству сна.
Существенные грани предлагаемого решения:
- Общая база данных и строка подключения,
- Общее имя участника программы,
- Общий раздел machineKey, так что каждый сайт будет использовать тикет общих форм.
- A UNIQUE имя приложения поставщика ролей (или, как вы говорите, projectId).
- Модифицированный
aspnet_Users_DeleteUser
sproc.
Модификация aspnet_Users_DeleteUser включает в себя очистку пользовательских ссылок в aspnet_users, которые динамически создаются поставщиками ролей и профилей, и содержит условие, что конкретный экземпляр aspnet_db принадлежит общему члену MembershipProvider и только к нему должны подключаться сайты, которые используют этого общего провайдера.
Чтобы отобразить это решение в сценарии OP:
Каждая учетная запись / компания будет иметь отдельный экземпляр aspnet_db, и «ProjectId» будет привязан к атрибуту applicationName элемента поставщика RoleManager.
Поскольку проекты «переносятся», им присваивается новый ProjectId (applicationName), и при этом пользователи компаний могут проходить аутентификацию на перенесенном проекте с помощью поставщика общего членства, но роли из исходного проекта не переносятся. в силу различных поставщиков ролей.
Все стандартные стратегии управления членством, например, Инструмент конфигурации AspNet, элементы управления входом в систему, мастера создания пользователей, функции членства (особенно Membership.DeleteUser () - спасибо Томасу) будут работать, как и ожидалось, без изменений.
Профили могут быть реализованы в любом направлении; использование applicationId провайдера Членства позволит данным профиля следовать за пользователем в любом из связанных проектов. Использование отдельного ProjectId (applicationName) поставщика ролей позволит создать отдельные профили для каждого пользователя в каждом проекте.
Более подробно и тесты здесь .
Существенные разделы конфигурации перечислены ниже, а затем измененный sproc.
Web.config
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="testDb" providerName="System.Data.SqlClient" connectionString="Data Source=(local);Initial Catalog=__SingleAuthMultiRole;Integrated Security=True"/>
</connectionStrings>
<system.web>
<compilation debug="true"/>
<!-- this key is common all your apps - generate a new one @ http://www.developmentnow.com/articles/machinekey_generator.aspx -->
<machineKey validationKey="841FEF8E55CD7963CE9EAFED329724667D62F4412F635815DFDDBE7D2D8D15819AE0FDF70CEF8F72792DBD7BF661F163B01134092CBCB80D7D71EAA42DFBF0A9" decryptionKey="FC9B0626224B0CF0DA68C558577F3E37723BB09AACE795498C4069A490690669" validation="SHA1" decryption="AES"/>
<authorization>
<deny users="?"/>
</authorization>
<authentication mode="Forms" />
<membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add name="SqlProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="testDb"
applicationName="Common" /> <!-- membership applicationName is common to all projects -->
</providers>
</membership>
<roleManager enabled="true" defaultProvider="SqlRoleManager" cacheRolesInCookie="true">
<providers>
<add name="SqlRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="testDb"
applicationName="WebApplication1"/> <!-- roleManager applicationName is unique to each projects -->
</providers>
</roleManager>
</system.web>
</configuration>
Использование :
После предоставления Aspnet_db файла aspnet_regsql.exe, запустите этот сценарий, чтобы изменить sproc aspnet_Users_DeleteUser.
/*************************************************************/
/*************************************************************/
--- Modified DeleteUser SP
IF (EXISTS (SELECT name
FROM sysobjects
WHERE (name = N'aspnet_Users_DeleteUser')
AND (type = 'P')))
DROP PROCEDURE [dbo].aspnet_Users_DeleteUser
GO
CREATE PROCEDURE [dbo].[aspnet_Users_DeleteUser]
@ApplicationName nvarchar(256),
@UserName nvarchar(256),
@TablesToDeleteFrom int,
@NumTablesDeletedFrom int OUTPUT
AS
BEGIN
-- holds all user id for username
DECLARE @UserIds TABLE(UserId UNIQUEIDENTIFIER)
SELECT @NumTablesDeletedFrom = 0
DECLARE @TranStarted bit
SET @TranStarted = 0
IF( @@TRANCOUNT = 0 )
BEGIN
BEGIN TRANSACTION
SET @TranStarted = 1
END
ELSE
SET @TranStarted = 0
DECLARE @ErrorCode int
DECLARE @RowCount int
SET @ErrorCode = 0
SET @RowCount = 0
-- get all userid for username
INSERT INTO @UserIds
SELECT UserId
FROM dbo.aspnet_Users
WHERE LoweredUserName = LOWER(@UserName)
DECLARE @tmp int
SELECT @tmp = COUNT(*) FROM @UserIds
IF NOT EXISTS(SELECT * FROM @UserIds)
GOTO Cleanup
-- Delete from Membership table if (@TablesToDeleteFrom & 1) is set
IF ((@TablesToDeleteFrom & 1) <> 0 AND
(EXISTS (SELECT name FROM sysobjects WHERE (name = N'vw_aspnet_MembershipUsers') AND (type = 'V'))))
BEGIN
DELETE FROM dbo.aspnet_Membership WHERE UserId IN (SELECT UserId from @UserIds)
SELECT @ErrorCode = @@ERROR,
@RowCount = @@ROWCOUNT
IF( @ErrorCode <> 0 )
GOTO Cleanup
IF (@RowCount <> 0)
SELECT @NumTablesDeletedFrom = @NumTablesDeletedFrom + 1
END
-- Delete from aspnet_UsersInRoles table if (@TablesToDeleteFrom & 2) is set
IF ((@TablesToDeleteFrom & 2) <> 0 AND
(EXISTS (SELECT name FROM sysobjects WHERE (name = N'vw_aspnet_UsersInRoles') AND (type = 'V'))) )
BEGIN
DELETE FROM dbo.aspnet_UsersInRoles WHERE UserId IN (SELECT UserId from @UserIds)
SELECT @ErrorCode = @@ERROR,
@RowCount = @@ROWCOUNT
IF( @ErrorCode <> 0 )
GOTO Cleanup
IF (@RowCount <> 0)
SELECT @NumTablesDeletedFrom = @NumTablesDeletedFrom + 1
END
-- Delete from aspnet_Profile table if (@TablesToDeleteFrom & 4) is set
IF ((@TablesToDeleteFrom & 4) <> 0 AND
(EXISTS (SELECT name FROM sysobjects WHERE (name = N'vw_aspnet_Profiles') AND (type = 'V'))) )
BEGIN
DELETE FROM dbo.aspnet_Profile WHERE UserId IN (SELECT UserId from @UserIds)
SELECT @ErrorCode = @@ERROR,
@RowCount = @@ROWCOUNT
IF( @ErrorCode <> 0 )
GOTO Cleanup
IF (@RowCount <> 0)
SELECT @NumTablesDeletedFrom = @NumTablesDeletedFrom + 1
END
-- Delete from aspnet_PersonalizationPerUser table if (@TablesToDeleteFrom & 8) is set
IF ((@TablesToDeleteFrom & 8) <> 0 AND
(EXISTS (SELECT name FROM sysobjects WHERE (name = N'vw_aspnet_WebPartState_User') AND (type = 'V'))) )
BEGIN
DELETE FROM dbo.aspnet_PersonalizationPerUser WHERE UserId IN (SELECT UserId from @UserIds)
SELECT @ErrorCode = @@ERROR,
@RowCount = @@ROWCOUNT
IF( @ErrorCode <> 0 )
GOTO Cleanup
IF (@RowCount <> 0)
SELECT @NumTablesDeletedFrom = @NumTablesDeletedFrom + 1
END
-- Delete from aspnet_Users table if (@TablesToDeleteFrom & 1,2,4 & 8) are all set
IF ((@TablesToDeleteFrom & 1) <> 0 AND
(@TablesToDeleteFrom & 2) <> 0 AND
(@TablesToDeleteFrom & 4) <> 0 AND
(@TablesToDeleteFrom & 8) <> 0 AND
(EXISTS (SELECT UserId FROM dbo.aspnet_Users WHERE UserId IN (SELECT UserId from @UserIds))))
BEGIN
DELETE FROM dbo.aspnet_Users WHERE UserId IN (SELECT UserId from @UserIds)
SELECT @ErrorCode = @@ERROR,
@RowCount = @@ROWCOUNT
IF( @ErrorCode <> 0 )
GOTO Cleanup
IF (@RowCount <> 0)
SELECT @NumTablesDeletedFrom = @NumTablesDeletedFrom + 1
END
IF( @TranStarted = 1 )
BEGIN
SET @TranStarted = 0
COMMIT TRANSACTION
END
RETURN 0
Cleanup:
SET @NumTablesDeletedFrom = 0
IF( @TranStarted = 1 )
BEGIN
SET @TranStarted = 0
ROLLBACK TRANSACTION
END
RETURN @ErrorCode
END
GO