服务器主体无法在SQL Server MS 2012中的当前安全上下文下访问数据库

Mav*_*ven 91 sql-server sql-server-2012

我试图通过SQL Server Management Studio访问我的托管服务器的数据库,所有东西,直到登录是好的,但当我使用命令use myDatabase它给我这个错误:

The server principal "****" is not able to access the database "****" under the current security context.
Run Code Online (Sandbox Code Playgroud)

我搜索了一下,托管服务提供商列出了这个问题的修复程序.

但这对我不起作用可能是因为它适用于SQL Server Management Studio 2008但是我使用的是SQL Server Management Studio 2012.

这可能是个问题吗?如果是,那么任何人都可以在SSMS 2012中告诉我它的替代方案吗?

小智 77

检查您的用户是否已映射到您尝试登录的数据库.

  • 你是怎样做的? (63认同)
  • 我建议寻找触发器,这就是我收到此消息的原因,在我的用户未经授权的另一个数据库中有触发器执行某些操作. (5认同)
  • @Graham使用SQL Server Management Studio检查用户或查看此答案:http://stackoverflow.com/a/9356725/804773 (3认同)
  • 我遇到了 OP 的错误并回答了这个答案,我发现我在连接到 Azure SQL 数据库的连接字符串中的数据库名称中有一个愚蠢的错字。如果您的数据库名称正确,则不需要访问 Master。如果它是错误的,那么(在我的情况下)我认为 Entity Framework (6.1.3) 试图通过连接到 Master 以获取一些附加信息来变得更加智能(尽管这可能与 EF 无关 - 我不确定)。但我的解决方案是确保我的连接字符串是正确的。我预计错误的数据库名称会出现非常不同的错误。:-/ (2认同)
  • 要添加到@DanielV的注释中,还请检查存储过程中是否有任何硬编码的数据库名称。在我的情况下已修复(必须更改大约20个存储过程)。 (2认同)

Ano*_*ous 20

我们在PROD环境中将报告部署到SSRS时遇到了同样的错误.人们发现这个问题甚至可以通过"使用"声明再现.解决方案是将用户的GUID帐户引用与相关数据库重新同步(即,像恢复数据库一样使用"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
Run Code Online (Sandbox Code Playgroud)

  • 为我工作 谢谢。我已将具有 SQL 服务器身份验证的数据库复制到我的测试服务器,但无法访问。现在它是 (2认同)

Tob*_*s J 15

SQL登录在服务器级别定义,并且必须映射到特定数据库中的用户

在 SSMS 对象资源管理器中,在您要修改的服务器下,展开Security > Logins,然后双击相应的登录条目。这将打开“登录属性”对话框。

选择User Mapping,这将显示服务器上的所有数据库。那些已经将用户映射到该登录名的用户将选中“映射”复选框。从这里您可以选择其他数据库(并确保选择用户应属于每个数据库中的哪些角色),然后单击“确定”以添加映射。

请注意,虽然通常的做法是将用户命名为与登录名相同的名称以避免混淆,但它们不必匹配,您可以随意命名用户。

在此处输入图片说明

在还原或类似操作之后,这些映射可能会断开连接。在这种情况下,用户可能仍然存在于数据库中,但实际上并未映射到登录名。如果发生这种情况,您可以运行以下命令来恢复登录:

USE {database};
ALTER USER {user} WITH login = {login}
Run Code Online (Sandbox Code Playgroud)

您还可以删除数据库用户并从登录属性对话框重新创建它,但需要重新创建任何角色成员资格或其他设置。

  • 您的评论应该是被接受的答案。它清楚地描述了: - SQL 登录位于*服务器级别* - SQL 用户位于*数据库级别* - 将登录映射到用户*缺少操作项* (2认同)
  • 很好的答案。这正是我所需要的。谢谢你! (2认同)
  • 使用{数据库};ALTER USER {user}WITH login = {login} 就是那个人。谢谢 (2认同)

小智 14

这对我有用:

use <Database>
EXEC  sp_change_users_login @Action='update_one', @UserNamePattern='<userLogin>',@LoginName='<userLogin>';
Run Code Online (Sandbox Code Playgroud)

该问题可以通过以下方式可视化:

SELECT sid FROM sys.sysusers WHERE name = '<userLogin>'
SELECT sid FROM sys.syslogins WHERE name = '<userLogin>';
Run Code Online (Sandbox Code Playgroud)

  • 这为我解决了这个问题。谢谢 !“问题可以通过以下方式可视化” -&gt; 如果它们返回不同的哈希值,则存在问题,上面的查询将同步它们。 (2认同)

Phi*_*uth 7

我花了很长时间来解决这个问题然后我意识到我犯了一个简单的错误,因为我忘记了哪个特定的数据库是我的目标.我使用标准SQL Server连接窗口输入凭据:

SQL Server连接窗口

我必须检查" 连接属性"选项卡以验证我是否选择了要连接的正确数据库.我不小心将Connect to database选项设置为上一个会话中的选择.这就是为什么我无法连接到我认为我想连接到的数据库.

连接属性

请注意,您需要单击该Options >>按钮才能显示" 连接属性"和其他选项卡.

  • 这对我有用,因为我登录的用户只能访问特定的数据库。谢谢! (2认同)

小智 6

在此之前,没有一个出色的答案可以解决我的边缘案例问题。就我而言,“以用户身份执行”语句在调用执行存储过程之前,但该过程是从不同数据库中的表读取的。即使用户是系统管理员,存储过程也会因“在当前安全上下文下”无法访问第二个数据库而失败。这在生产中有效,但在我们的开发环境中失败。我看到在生产中,可信赖在初始数据库中设置为“打开”,但在开发中的数据库上设置为“打开”。我读到,恢复数据库时(当我们不时将生产数据库恢复到我们的开发环境时)会产生关闭可信功能的效果。在 dev 中将其设置为“on”允许用户对第二个数据库进行读取访问。


Sal*_*gji 5

我相信您在创建数据库用户时可能缺少“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
Run Code Online (Sandbox Code Playgroud)