Máy chủ chính không thể truy cập cơ sở dữ liệu trong bối cảnh bảo mật hiện tại trong SQL Server MS 2012


103

Tôi đang cố gắng truy cập cơ sở dữ liệu của máy chủ lưu trữ của mình thông qua SQL Server Management Studio, mọi thứ cho đến khi đăng nhập đều ổn nhưng khi tôi sử dụng lệnh, use myDatabasenó cho tôi lỗi này:

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

Tôi đã tìm kiếm và các nhà cung cấp dịch vụ lưu trữ đã liệt kê cách khắc phục sự cố này.

Nhưng điều này không hoạt động với tôi có lẽ vì nó dành cho SQL Server Management Studio 2008 tuy nhiên tôi đang sử dụng SQL Server Management Studio 2012.

Đây có thể là một vấn đề? Và nếu có, bất cứ ai có thể cho tôi biết sự thay thế của nó trong SSMS 2012?


3
'Nhà cung cấp dịch vụ lưu trữ'? Chúng ta đang nói chuyện riêng hay chia sẻ? Nếu đó là máy chủ lưu trữ được chia sẻ, tôi thực sự khuyên bạn nên liên hệ với nhà cung cấp dịch vụ lưu trữ của mình để được hỗ trợ. SQL trong môi trường lưu trữ được chia sẻ nổi tiếng là nhiều lỗi và có vấn đề. Nó không liên quan gì đến sản phẩm nhưng các chính sách mà nhà cung cấp dịch vụ lưu trữ áp dụng cho (các) máy chủ. Mọi công ty lưu trữ đều có cách riêng của họ để tận dụng SQL hoặc có vẻ như vậy.
Techie Joe

Câu trả lời:


80

Kiểm tra xem liệu người dùng của bạn có được ánh xạ tới DB mà bạn đang cố gắng đăng nhập hay không.


76
làm thế nào để bạn làm điều đó?
Graham

3
@Graham Hoặc sử dụng SQL Server Management Studio để kiểm tra tài khoản hoặc xem câu trả lời này: stackoverflow.com/a/9356725/804773
Grambot

5
Tôi đề nghị tìm kiếm trình kích hoạt, đó là lý do tôi nhận được thông báo này, có một trình kích hoạt đang thực hiện một số công việc trong cơ sở dữ liệu khác mà người dùng của tôi không được phép.
DanielV

1
Tôi đã gặp lỗi của OP và các bể chứa cho câu trả lời này, tôi phát hiện ra rằng tôi vừa mắc phải lỗi đánh máy ngu ngốc trong Tên cơ sở dữ liệu trong chuỗi kết nối của tôi kết nối với Cơ sở dữ liệu Azure SQL. Nếu Tên cơ sở dữ liệu của bạn chính xác, bạn không cần truy cập vào Master. Nếu sai, thì (trong trường hợp của tôi) tôi nghĩ Entity Framework (6.1.3) đang cố gắng trở nên thông minh hơn bằng cách kết nối với Master để biết thêm một số thông tin (mặc dù điều đó có thể không liên quan đến EF - tôi không chắc). Nhưng giải pháp của tôi là đảm bảo rằng kết nối của tôi là chính xác. Tôi mong đợi một lỗi rất khác cho một tên cơ sở dữ liệu không hợp lệ. : - /
Jaxidian

2
Để thêm vào nhận xét của @ DanielV, hãy kiểm tra Quy trình lưu trữ để biết bất kỳ tên cơ sở dữ liệu được mã hóa cứng nào. Đã sửa nó trong trường hợp của tôi (khoảng 20 thủ tục được lưu trữ phải được thay đổi).
Demonslay335

26

Chúng tôi đã gặp lỗi tương tự khi triển khai báo cáo tới SSRS trong môi trường PROD của chúng tôi. Nó đã được tìm thấy vấn đề thậm chí có thể được tái tạo với một tuyên bố "sử dụng". Giải pháp là đồng bộ hóa lại tham chiếu tài khoản GUID của người dùng với cơ sở dữ liệu được đề cập (tức là sử dụng "sp_change_users_login" giống như cách bạn làm sau khi khôi phục db). Tập lệnh stock (điều khiển bằng con trỏ) để đồng bộ hóa lại tất cả các tài khoản được đính kèm:

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
Làm việc cho tôi Cảm ơn bạn. Tôi đã sao chép cơ sở dữ liệu có xác thực máy chủ SQL vào máy chủ thử nghiệm của mình và nó không thể truy cập được. Bây giờ là
MikeH

1
Nếu Người dùng tồn tại trong cơ sở dữ liệu nhưng không tiếp tục ánh xạ tới Đăng nhập, thì việc xóa Người dùng đã nói qua SSMS Object Explorer, sau đó ánh xạ lại Đăng nhập phù hợp với tôi. Nếu không, tôi nghi ngờ giải pháp được đề xuất ở trên sẽ cần được thực hiện.
jjt

10

Tôi đã dành khá nhiều thời gian để vật lộn với vấn đề này và sau đó tôi nhận ra rằng tôi đã mắc một sai lầm đơn giản là tôi đã quên cơ sở dữ liệu cụ thể nào mà tôi đang nhắm mục tiêu kết nối của mình. Tôi đang sử dụng cửa sổ kết nối SQL Server tiêu chuẩn để nhập thông tin đăng nhập:

Cửa sổ kết nối máy chủ SQL

Tôi phải kiểm tra tab Thuộc tính kết nối để xác minh rằng tôi đã chọn đúng cơ sở dữ liệu để kết nối. Tôi đã vô tình để tùy chọn Kết nối với cơ sở dữ liệu ở đây được đặt thành lựa chọn từ phiên trước. Đây là lý do tại sao tôi không thể kết nối với cơ sở dữ liệu mà tôi nghĩ rằng tôi đang cố gắng kết nối.

Thuộc tính kết nối

Lưu ý rằng bạn cần nhấp vào Options >>nút để Thuộc tính kết nối và các tab khác hiển thị.


10

Điều này đã làm việc cho tôi:

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

Vấn đề có thể được hình dung bằng:

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

2
CÁi này đã sửa nó giúp tôi. Cảm ơn ! "Vấn đề có thể được hình dung bằng" -> Nếu chúng trả về một hàm băm khác, thì có vấn đề và truy vấn ở trên sẽ đồng bộ chúng.
bezout,

6

Nhật SQL được xác định ở cấp máy chủ và phải được ánh xạ tới Người dùng trong cơ sở dữ liệu cụ thể.

Trong trình khám phá đối tượng SSMS, bên dưới máy chủ bạn muốn sửa đổi, hãy mở rộng Bảo mật > Đăng nhập , sau đó bấm đúp vào người dùng thích hợp sẽ xuất hiện hộp thoại "Thuộc tính đăng nhập".

Chọn Bản đồ người dùng , sẽ hiển thị tất cả cơ sở dữ liệu trên máy chủ, với những cơ sở dữ liệu có ánh xạ hiện có được chọn. Từ đây, bạn có thể chọn cơ sở dữ liệu bổ sung (và đảm bảo chọn vai trò nào trong mỗi cơ sở dữ liệu mà người dùng phải thuộc về), sau đó bấm OK để thêm ánh xạ.

nhập mô tả hình ảnh ở đây

Các ánh xạ này có thể bị ngắt kết nối sau khi khôi phục hoặc thao tác tương tự. Trong trường hợp này, người dùng có thể vẫn tồn tại trong cơ sở dữ liệu nhưng không thực sự được ánh xạ tới đăng nhập. Nếu điều đó xảy ra, bạn có thể chạy như sau để khôi phục thông tin đăng nhập:

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

Bạn cũng có thể xóa người dùng DB và tạo lại nó từ hộp thoại Thuộc tính đăng nhập, nhưng bất kỳ tư cách thành viên vai trò nào hoặc các cài đặt khác sẽ cần được tạo lại.


4

Trong trường hợp của tôi, thông báo là do một từ đồng nghĩa vô tình bao gồm tên cơ sở dữ liệu trong "tên đối tượng". Khi tôi khôi phục cơ sở dữ liệu dưới một tên mới, từ đồng nghĩa vẫn trỏ đến tên DB cũ. Vì người dùng không có quyền trong DB cũ, thông báo xuất hiện. Để khắc phục, tôi đã loại bỏ và tạo lại từ đồng nghĩa mà không xác định tên đối tượng với tên cơ sở dữ liệu:

    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

Chúng tôi đã gặp lỗi tương tự mặc dù người dùng đã được ánh xạ đúng cách đến thông tin đăng nhập.

Sau khi cố gắng xóa người dùng, người ta phát hiện ra rằng một số SP chứa "với thực thi là" người dùng đó.

Vấn đề đã được giải quyết bằng cách bỏ các SP đó, bỏ người dùng, tạo lại người dùng được liên kết để đăng nhập và tạo lại các SP.

Có thể nó ở trạng thái này do khôi phục từ bản sao lưu (trong thời gian khi đăng nhập liên quan không tồn tại) hoặc đồng bộ hóa lược đồ hàng loạt (nếu có thể tạo SP với thực thi ngay cả khi người dùng không tồn tại. Cũng có thể có có liên quan đến câu trả lời này .


1
Bạn có thể nói rõ hơn về ý nghĩa của SP không?
Scuba Steve

1
Thủ tục lưu trữ. Khi tạo SP (create proc xxx ...), có một mệnh đề tùy chọn "với execute as <user>" chỉ định rằng SP sẽ chạy như thể người dùng đó đã chạy nó thay vì người dùng hiện đang đăng nhập.
crokusek

1

Tôi gặp phải lỗi tương tự khi sử dụng Đối tượng quản lý máy chủ (SMO) trong vb.net (tôi chắc chắn rằng nó giống nhau trong C #)

Nhận xét của Techie Joe về bài đăng đầu tiên là một lời cảnh báo hữu ích rằng trong chia sẻ lưu trữ có rất nhiều thứ bổ sung đang diễn ra. Phải mất một chút thời gian để tìm ra, nhưng đoạn mã dưới đây cho thấy cách một người phải rất cụ thể trong cách họ truy cập cơ sở dữ liệu SQL. Lỗi 'máy chủ chính ...' dường như xuất hiện bất cứ khi nào các lệnh gọi SMO không chính xác cụ thể trong môi trường lưu trữ được chia sẻ.

Đoạn mã đầu tiên này chống lại máy chủ SQL Express cục bộ và dựa trên Xác thực Windows đơn giản. Tất cả mã được sử dụng trong các mẫu này đều dựa trên hướng dẫn SMO của Robert Kanasz trong bài viết trên trang web Dự án Mã này :

  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

Đoạn mã trên tìm thấy các tệp .mdf cho mọi cơ sở dữ liệu trên máy chủ SQLEXPRESS cục bộ tốt vì quá trình xác thực được Windows xử lý và nó có phạm vi rộng trên tất cả các cơ sở dữ liệu.

Trong đoạn mã sau, có 2 phần lặp lại cho các tệp .mdf. Trong trường hợp này, chỉ lần lặp đầu tiên tìm kiếm nhóm tệp mới hoạt động và nó chỉ tìm thấy một tệp duy nhất vì kết nối chỉ đến một cơ sở dữ liệu duy nhất trong môi trường lưu trữ được chia sẻ.

Lần lặp thứ hai, là một bản sao của lần lặp đã hoạt động ở trên, bị nghẹt ngay lập tức vì cách nó được viết cố gắng truy cập cơ sở dữ liệu thứ nhất trong môi trường chia sẻ, không phải là cơ sở dữ liệu mà User ID / Password áp dụng, vì vậy máy chủ SQL trả về lỗi ủy quyền ở dạng lỗi 'máy chủ chính ...'.

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

Trong vòng lặp thứ hai đó, mã biên dịch tốt, nhưng vì SMO không được thiết lập để truy cập chính xác cơ sở dữ liệu chính xác với cú pháp chính xác, nỗ lực đó không thành công.

Vì tôi chỉ mới học SMO, tôi nghĩ những người mới khác có thể đánh giá cao khi biết rằng cũng có một lời giải thích đơn giản hơn cho lỗi này - chúng tôi chỉ mã hóa sai.


0

Tôi tin rằng bạn có thể thiếu câu lệnh "Grant Connect To" khi bạn tạo người dùng cơ sở dữ liệu.

Dưới đây là đoạn mã hoàn chỉnh mà bạn sẽ cần để tạo cả thông tin đăng nhập vào SQL Server DBMS cũng như người dùng đối với cơ sở dữ liệu

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.