서버 보안 주체는 SQL Server MS 2012의 현재 보안 컨텍스트에서 데이터베이스에 액세스 할 수 없습니다.


103

SQL Server Management Studio를 통해 호스팅 서버의 데이터베이스에 액세스하려고합니다. 로그인 할 때까지 모든 것이 정상이지만 명령을 사용하면 use myDatabase이 오류가 발생합니다.

The server principal "****" is not able to access the database "****" under the current security context.

검색 결과 호스팅 서비스 제공 업체가 문제에 대한 수정 사항을 나열 했습니다 .

그러나 이것은 아마도 SQL Server Management Studio 2008 용이기 때문에 작동하지 않지만 SQL Server Management Studio 2012를 사용하고 있습니다.

이것이 문제가 될 수 있습니까? 그렇다면 누구든지 SSMS 2012에서 대안을 말할 수 있습니까?


3
'호스팅 서비스 제공 업체'? 우리는 헌신적입니까, 공유입니까? 공유 호스팅 서버 인 경우 호스팅 제공 업체에 도움을 요청하는 것이 좋습니다. 공유 호스팅 환경의 SQL은 버그가 많고 문제가있는 것으로 악명이 높습니다. 제품과는 아무런 관련이 없지만 호스팅 제공 업체가 서버에 적용하는 정책입니다. 모든 호스팅 회사에는 SQL을 활용하는 자체 방법이 있습니다.
Techie Joe

답변:


80

로그인하려는 DB에 사용자가 매핑되어 있는지 확인하십시오.


76
어떻게 하죠?
Graham

3
@Graham SQL Server Management Studio를 사용하여 사용자를 확인하거나 다음 답변을 참조하십시오. stackoverflow.com/a/9356725/804773
Grambot

5
트리거를 찾는 것이 좋습니다. 이것이 제가이 메시지를받은 이유였습니다. 내 사용자가 승인되지 않은 다른 데이터베이스에서 어떤 작업을 수행하는 트리거가있었습니다.
DanielV

1
이 답변에 OP의 오류와 탱크가 발생했습니다 .Azure SQL Database에 연결하는 연결 문자열의 데이터베이스 이름에 어리석은 오타가 있음을 알았습니다. 데이터베이스 이름이 정확하면 Master에 액세스 할 필요가 없습니다. 그것이 틀렸다면 (내 경우에는) Entity Framework (6.1.3)가 몇 가지 추가 정보를 위해 Master에 연결하여 더 똑똑해 지려고 노력하고 있다고 생각합니다 (그것이 EF와 관련이 없을 수 있지만 확실하지 않습니다). 그러나 내 해결책은 내 연결 문자열이 올바른지 확인하는 것이 었습니다. 잘못된 데이터베이스 이름에 대해 매우 다른 오류가 발생할 것으로 예상했습니다. : - /
Jaxidian

2
@DanielV의 주석에 추가하려면 하드 코딩 된 데이터베이스 이름에 대한 저장 프로시 저도 확인하십시오. 제 경우에는 수정했습니다 (약 20 개의 저장 프로 시저를 변경해야 함).
Demonslay335

26

PROD 환경에서 SSRS에 보고서를 배포하는 동안 동일한 오류가 발생했습니다. 문제는 "사용"문구로 재현 할 수도 있다는 사실을 발견했습니다. 해결책은 사용자의 GUID 계정 참조를 문제의 데이터베이스와 다시 동기화하는 것입니다 (예 : db를 복원 한 후처럼 "sp_change_users_login"사용). 모든 계정을 다시 동기화하는 주식 (커서 기반) 스크립트가 첨부됩니다.

USE <your database>
GO

-------- Reset SQL user account guids ---------------------
DECLARE @UserName nvarchar(255) 
DECLARE orphanuser_cur cursor for 
      SELECT UserName = su.name 
      FROM sysusers su
      JOIN sys.server_principals sp ON sp.name = su.name
      WHERE issqluser = 1 AND
            (su.sid IS NOT NULL AND su.sid <> 0x0) AND
            suser_sname(su.sid) is null 
      ORDER BY su.name 

OPEN orphanuser_cur 
FETCH NEXT FROM orphanuser_cur INTO @UserName 

WHILE (@@fetch_status = 0)
BEGIN 
--PRINT @UserName + ' user name being resynced' 
exec sp_change_users_login 'Update_one', @UserName, @UserName 
FETCH NEXT FROM orphanuser_cur INTO @UserName 
END 

CLOSE orphanuser_cur 
DEALLOCATE orphanuser_cur

2
나를 위해 일했습니다. 감사합니다. SQL 서버 인증이있는 데이터베이스를 테스트 서버에 복사했는데 액세스 할 수 없었습니다. 지금은
MikeH

1
사용자가 데이터베이스에 있지만 로그인에 대한 매핑을 유지하지 못하는 경우 SSMS 개체 탐색기를 통해 해당 사용자를 삭제 한 다음 로그인을 다시 매핑하는 것이 효과적이었습니다. 그렇지 않으면 위에서 제안한 해결책을 취해야 할 것 같습니다.
jjt

10

나는이 문제와 씨름하는 데 꽤 오랜 시간을 보냈고, 내가 내 연결을 목표로 삼고있는 특정 데이터베이스를 잊었다는 사실에 간단한 실수를하고 있다는 것을 깨달았다. 표준 SQL Server 연결 창을 사용하여 자격 증명을 입력했습니다.

SQL Server 연결 창

나는 확인했다 연결 속성 I 연결할 올바른 데이터베이스를 선택되었는지 확인하는 탭을 선택합니다. 실수 로 데이터베이스에 연결 옵션을 이전 세션의 선택 항목으로 설정했습니다. 이것이 제가 연결 하려고 했던 데이터베이스에 연결할 수없는 이유 입니다.

연결 속성

연결 속성 및 기타 탭을 표시 하려면 Options >>단추 를 클릭해야 합니다.


10

이것은 나를 위해 일했습니다.

use <Database>
EXEC  sp_change_users_login @Action='update_one', @UserNamePattern='<userLogin>',@LoginName='<userLogin>';

문제는 다음과 같이 시각화 할 수 있습니다.

SELECT sid FROM sys.sysusers WHERE name = '<userLogin>'
SELECT sid FROM sys.syslogins WHERE name = '<userLogin>';

2
이것은 나를 위해 그것을 고쳤습니다. 감사 ! "문제는 다음으로 시각화 할 수 있습니다."-> 다른 해시를 반환하면 문제가있는 것이며 위의 쿼리가이를 동기화합니다.
bezout

7

SQL 로그인 은 서버 수준에서 정의되며 특정 데이터베이스의 사용자 에 매핑되어야 합니다.

SSMS 개체 탐색기에서 수정하려는 서버 아래에서 보안 > 로그인을 확장 한 다음 적절한 사용자를 두 번 클릭하면 "로그인 속성"대화 상자가 나타납니다.

사용자 매핑을 선택 하면 기존 매핑이 선택된 데이터베이스와 함께 서버의 모든 데이터베이스가 표시됩니다. 여기에서 추가 데이터베이스를 선택한 다음 (사용자가 속해야하는 각 데이터베이스의 역할을 선택해야 함) 확인 을 클릭 하여 매핑을 추가 할 수 있습니다.

여기에 이미지 설명 입력

이러한 매핑은 복원 또는 유사한 작업 후에 연결이 끊어 질 수 있습니다. 이 경우 사용자는 데이터베이스에 여전히 존재할 수 있지만 실제로 로그인에 매핑되지는 않습니다. 이 경우 다음을 실행하여 로그인을 복원 할 수 있습니다.

USE {database};
ALTER USER {user} WITH login = {login}

DB 사용자를 삭제하고 로그인 속성 대화 상자에서 다시 만들 수도 있지만 모든 역할 멤버 자격 또는 기타 설정을 다시 만들어야합니다.


4

필자의 경우 메시지는 "개체 이름"에 데이터베이스 이름이 실수로 포함 된 동의어로 인해 발생했습니다. 새 이름으로 데이터베이스를 복원 할 때 동의어는 여전히 이전 DB 이름을 가리 킵니다. 사용자는 이전 DB에 대한 권한이 없기 때문에 메시지가 나타납니다. 수정하기 위해 데이터베이스 이름으로 개체 이름을 한정하지 않고 동의어를 삭제하고 다시 만들었습니다.

    USE [new_db]
GO

/****** Object:  Synonym [dbo].[synTable]    Script Date: 10/15/2015 9:45:01 AM ******/
DROP SYNONYM [dbo].[synTable]
GO

/****** Object:  Synonym [dbo].[synTable]    Script Date: 10/15/2015 9:45:01 AM ******/
CREATE SYNONYM [dbo].[synTable] FOR [dbo].[tTheRealTable]
GO

2

사용자가 로그인에 올바르게 매핑되었지만 동일한 오류가 발생했습니다.

사용자 삭제를 시도한 후 몇 개의 SP에 해당 사용자가 "다음 계정으로 실행"이 포함되어 있음이 발견되었습니다.

이 문제는 해당 SP를 삭제하고, 사용자를 삭제하고, 로그인에 연결된 사용자를 다시 생성하고, SP를 다시 생성하여 해결되었습니다.

백업에서 복원 (관련 로그인이 존재하지 않는 시간 동안) 또는 대량 스키마 동기화 (사용자가 존재하지 않는 것처럼 실행하여 SP를 생성 할 수있는 경우)에서이 상태가되었을 수 있습니다. 이 답변 과 관련 있습니다.


1
SP가 의미하는 바에 대해 자세히 설명해 주시겠습니까?
Scuba Steve

1
저장 프로 시저. SP를 생성 할 때 (create proc xxx ...) "with execute as <user>"라는 선택적 절이있어 SP가 현재 로그인 한 사용자 대신 해당 사용자가 실행 한 것처럼 실행되도록 지정합니다.
crokusek

1

vb.net에서 SMO (서버 관리 개체)를 사용하는 동안 동일한 오류가 발생했습니다 (C #에서도 동일 함).

초기 게시물에 대한 Techie Joe의 의견은 공유 호스팅에서 많은 추가 작업이 진행되고 있다는 유용한 경고였습니다. 알아내는 데 약간의 시간이 걸렸지 만 아래 코드는 SQL 데이터베이스에 액세스하는 방식이 매우 구체적이어야하는 방법을 보여줍니다. '서버 주체 ...'오류는 공유 호스팅 환경에서 SMO 호출이 정확히 구체적이지 않을 때마다 나타나는 것처럼 보였습니다.

이 코드의 첫 번째 섹션은 로컬 SQL Express 서버에 대한 것이며 간단한 Windows 인증에 의존했습니다. 이 샘플에 사용 된 모든 코드는이 코드 프로젝트 웹 사이트 기사 에서 Robert Kanasz의 SMO 튜토리얼을 기반으로합니다 .

  Dim conn2 = New ServerConnection()
  conn2.ServerInstance = "<local pc name>\SQLEXPRESS"
  Try
    Dim testConnection As New Server(conn2)
    Debug.WriteLine("Server: " + testConnection.Name)
    Debug.WriteLine("Edition: " + testConnection.Information.Edition)
    Debug.WriteLine(" ")

    For Each db2 As Database In testConnection.Databases
      Debug.Write(db2.Name & " - ")
      For Each fg As FileGroup In db2.FileGroups
        Debug.Write(fg.Name & " - ")
        For Each df As DataFile In fg.Files
          Debug.WriteLine(df.Name + " - " + df.FileName)
        Next
      Next
    Next
    conn2.Disconnect()

  Catch err As Exception
    Debug.WriteLine(err.Message)
  End Try

위의 코드는 인증이 Windows에서 처리되고 모든 데이터베이스에서 광범위하기 때문에 로컬 SQLEXPRESS 서버의 모든 데이터베이스에 대한 .mdf 파일을 찾습니다.

다음 코드에는 .mdf 파일에 대해 반복되는 2 개의 섹션이 있습니다. 이 경우 파일 그룹을 찾는 첫 번째 반복 만 작동하며 공유 호스팅 환경의 단일 데이터베이스에만 연결되므로 단일 파일 만 찾습니다.

위에서 작동 한 반복의 사본 인 두 번째 반복은 작성 방식이 사용자 ID / 비밀번호가 적용되는 것이 아닌 공유 환경에서 첫 번째 데이터베이스에 액세스하려고 시도하기 때문에 즉시 질식합니다. SQL 서버는 '서버 보안 주체 ...'오류 형식으로 권한 부여 오류를 반환합니다.

Dim sqlConnection1 As New System.Data.SqlClient.SqlConnection
sqlConnection1.ConnectionString = "connection string with User ID/Password to a specific database in a shared hosting system. This string will likely also include the Data Source and Initial Catalog parameters"
Dim conn1 As New ServerConnection(sqlConnection1)
Try
  Dim testConnection As New Server(conn1)
  Debug.WriteLine("Server: " + testConnection.Name)
  Debug.WriteLine("Edition: " + testConnection.Information.Edition)
  Debug.WriteLine(" ")

  Dim db2 = testConnection.Databases("the name of the database to which the User ID/Password in the connection string applies")
  For Each fg As FileGroup In db2.FileGroups
    Debug.Write(fg.Name & " - ")
    For Each df As DataFile In fg.Files
      Debug.WriteLine(df.Name + " - " + df.FileName)
    Next
  Next

  For Each db3 As Database In testConnection.Databases
    Debug.Write(db3.Name & " - ")
    For Each fg As FileGroup In db3.FileGroups
      Debug.Write(fg.Name & " - ")
      For Each df As DataFile In fg.Files
        Debug.WriteLine(df.Name + " - " + df.FileName)
      Next
    Next
  Next

  conn1.Disconnect()

Catch err As Exception
  Debug.WriteLine(err.Message)
End Try

두 번째 반복 루프에서 코드는 잘 컴파일되지만 SMO가 정확한 구문으로 정확한 데이터베이스에 정확하게 액세스하도록 설정되지 않았기 때문에이 시도는 실패합니다.

SMO를 배우는 중이기 때문에이 오류에 대한 더 간단한 설명이 있다는 사실을 알고있는 다른 초보자도 감사 할 것이라고 생각했습니다. 방금 잘못 코딩했습니다.


0

데이터베이스 사용자를 만들 때 "Grant Connect To"문이 누락되었을 수 있습니다.

다음은 SQL Server DBMS에 대한 로그인과 데이터베이스에 대한 사용자를 모두 생성하는 데 필요한 전체 스 니펫입니다.

USE [master]
GO

CREATE LOGIN [SqlServerLogin] WITH PASSWORD=N'Passwordxyz', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
GO

USE [myDatabase]
GO

CREATE USER [DatabaseUser] FOR LOGIN [SqlServerLogin] WITH DEFAULT_SCHEMA=[mySchema]
GO

GRANT CONNECT TO [DatabaseUser]
GO

-- the role membership below will allow you to run a test "select" query against the tables in your database
ALTER ROLE [db_datareader] ADD MEMBER [DatabaseUser]
GO
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.