5

프로덕션 환경으로 마이그레이션하고 있습니다. DBA가 aspnet_regsql으로 생성 한 스크립트를 실행 한 직후에 역할을 가진 사용자를 생성 할 수있는 스크립트를 작성하고 싶습니다. 개발 환경에서 Global.asax.cs에 회원 공급자의 API가있는 사용자와 역할을 추가했습니다. 그러나 나는이 하드 코드 방식을 피하고 싶다. 이제 T-SQL의 exprience 부족이 드러났습니다. 다음 스크립트를 작성했습니다.이 스크립트는 한꺼번에 실행하지 않으면 작동합니다.SQLMembershipProvider에 대해 SQL에서 사용자와 역할을 추가하는 방법은 무엇입니까?

Use MyApps_Prod; 
GO 

DECLARE @user_identity CHAR(40); 
DECLARE @scalar_userid AS NVARCHAR(255); 
DECLARE @scalar_roleid AS NVARCHAR(255); 
DECLARE @app_id AS NVARCHAR(255); 
SET @user_identity = N'AMERICAS\First.Last'; 

SET @app_id = (SELECT DISTINCT ApplicationId 
      FROM [dbo].[aspnet_Applications] 
      WHERE loweredapplicationname = 'MyApplication'); 
SELECT * FROM [dbo].[aspnet_Users] WHERE UserName = @user_identity 

IF NOT EXISTS (SELECT * FROM [dbo].[aspnet_Users] WHERE UserName = @user_identity) 
BEGIN 
    INSERT INTO [dbo].aspnet_Users 
      ([ApplicationId], [UserName], [LoweredUserName], [LastActivityDate]) 
    VALUES 
     (@app_id, @user_identity, LOWER(@user_identity), GETDATE()); 
END; 

DECLARE @role_name CHAR(40); 
SET @role_name = N'Communicator'; 
IF NOT EXISTS (SELECT * FROM [dbo].[aspnet_Roles] WHERE RoleName = @role_name) 
BEGIN 
    INSERT INTO [dbo].[aspnet_Roles] 
     ([ApplicationId], [RoleName], [LoweredRoleName]) 
    VALUES 
     (@app_id, @role_name, LOWER(@role_name)) 
END; 


SET @scalar_userid = (SELECT DISTINCT UserID FROM [dbo].aspnet_Users WHERE UserName = @user_identity); 
SET @scalar_roleid = (SELECT DISTINCT RoleID FROM [dbo].aspnet_Roles WHERE RoleName = @role_name); 

INSERT INTO [dbo].aspnet_UsersInRoles (UserID, RoleID) 
    VALUES (
     @scalar_userid , 
     @scalar_roleid 
    ); 


SET @role_name = N'AccessAdministrator'; 
IF NOT EXISTS (SELECT * FROM [dbo].[aspnet_Roles] WHERE RoleName = @role_name) 
BEGIN 
    INSERT INTO [dbo].[aspnet_Roles] 
     ([ApplicationId], [RoleName], [LoweredRoleName]) 
    VALUES 
     (@app_id, @role_name, LOWER(@role_name)) 
END; 


SET @scalar_roleid = (SELECT DISTINCT RoleID FROM [dbo].aspnet_Roles WHERE RoleName = @role_name); 

INSERT INTO [dbo].aspnet_UsersInRoles (UserID, RoleID) 
    VALUES (
     @scalar_userid , 
     @scalar_roleid 
    ); 
GO 

나는 내가 세미콜론으로 각 INSERT을 종료하면 작동하도록 INSERTs를 가져온 다음 GO을 추가 할 수 있음을 발견했다, 그러나 나는 재 선언하고 각 변수를 재 할당해야합니다.

어떻게 실제 SQL 개발자가이 작업을 수행합니까?

+0

모두 실패한 경우 v1의 경우 global.asax에두고 v2의 경우 제거하십시오. – Greg

답변

10

수동으로 INSERT 문을 작성하는 대신 SqlMembershipProvider 구현 공급자의 일부인 저장 프로 시저를 사용하고 aspnet_reg.exe 도구를 사용하여 응용 프로그램 서비스를 설치할 때 포함되는 저장 프로 시저를 사용하십시오. 특히

는 사용

  • aspnet_Roles_CreateRole
  • aspnet_UsersInRoles_AddUsersToRoles 사용자를 생성하고 자신의 회원 데이터 공급하기 위해 새로운 역할
  • aspnet_Membership_CreateUser을 생성 (비밀번호, 보안 질문과 대답 등)에 기존 사용자를 기존 역할에 추가하는 방법

aspnet_Membership_CreateUser은 많은 트릭 중 하나입니다. 암호를 일반 텍스트로 저장하지 않는다고 가정하면 해시 또는 암호화 된 버전을 @Password 매개 변수를 통해 sproc에 전달해야합니다.Reflector를 사용하여 SqlMembershipProvider 클래스의 코드 CreateUser method에서 코드를 검사하는 것이 좋습니다. 여기서 .NET이이 논리를 어떻게 처리하는지 볼 수 있습니다.

이렇게 스크립팅하는 대신 텍스트 파일을 읽고 지정된 역할, 사용자 및 사용자 역할 연결을 만드는 명령 줄 프로그램을 작성하는 것이 좋습니다. 이 명령 행 프로그램은 Membership API를 직접 사용하므로 모든 하위 레벨 세부 사항을 처리합니다. 그런 다음이 명령 줄 프로그램을 빌드 또는 배포 프로세스의 일부로 실행할 수 있습니다.

해피 프로그래밍!

+0

나는 커맨드 라인 제안을 좋아한다. – Greg

+0

이것은 매력처럼 작동했습니다. 감사. – Blanthor

2

SQL 프로필러를 실행하여 하드 코드 된 구현을 실행 해 보았습니까? 그것은 물건을 실행하는 정확한 순서를 보여 주어야합니다.

+0

나는 고마워 할 것이다. – Blanthor

+0

가능한 경우 데이터베이스에 포함 된 저장 프로 시저를 사용해야합니다. 프로파일 러는 프로파일 사용법을 보여 주어야합니다. – Greg

+0

+1 매우 도움이되었습니다. – Blanthor

0

"실제 SQL 개발자는 어떻게합니까?"

여기가 시작되었습니다. T-SQL은 배열을 직접 지원하지 않지만 일반적으로 테이블 변수를 배열로 처리하여 코드를 압축/재사용합니다. 귀하의 예에서는 큰 이익이 아닙니다. 그러나 10 개의 rolenames가 있다면 그것은 될 것입니다.

예 :


DECLARE @roles TABLE (rolename CHAR(40)); 
INSERT @roles 
SELECT 'Communicator' 
UNION ALL 
SELECT 'AccessAdministrator'; 
DECLARE @rolename CHAR(40); 

--loop through the @roles table variable like it's an array 
WHILE (SELECT COUNT(*) FROM @roles) > 0 
    BEGIN 
    SELECT TOP 1 @rolename = rolename FROM @roles; 
    --Do something with the current rolename 
    SELECT @rolename; 
    DELETE @roles WHERE rolename = @rolename; 
    END 
0

스크립트를 통해 그것을 만들 좋은 생각이 아니다. 또한 API를 사용하는 경우 수동으로 작성해야한다고 확신 할 수 없습니다. 기존 데이터를 이전 해 보셨습니까?

하지만 이것이 선택 인 경우 Reflector Tool을 사용하여 해당 멤버십/역할 메서드의 코드를 확인하시기 바랍니다. 암호화 된/해싱이있을 수 있기 때문에 저장된 proc을 실행하는 것만으로는 충분하지 않습니다. 적절한 applicationName을 선택하고 web.config에서 설정 한 여러 다른 검사가 저장된 API가 해당 API 메소드에 의해 실행되기 전에 수행해야합니다.

사용자 정보를 삽입 할 수 있기 때문에 모든 것을 고려해야하지만 사용하기를 원하면 API를 사용하면 다른 문제가 발생할 수 있습니다.

관련 문제