Windows用户创建表时,SQL 2008 R2创建用户/架构


9

我们添加了服务器登录名和数据库用户,该用户使用以下脚本将Windows组映射到SQL 2008 R2实例,并更改了名称以实现匿名:

USE master
go
CREATE LOGIN [DOMAIN\AppUsers] FROM WINDOWS
WITH DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]
go
USE AppDb
go
CREATE USER [DOMAIN\AppUsers] FOR LOGIN 
[DOMAIN\AppUsers]
go
EXEC sp_addrolemember N'db_owner', N'DOMAIN\AppUsers'
go

当DOMAIN \ User1帐户登录到应用程序时,User1可以在dbo模式中查询表,因为User1是DOMAIN \ AppUsers的成员,但是此应用程序也允许用户创建表。在不指定架构的情况下创建这些表时,SQL Server会执行以下操作:

  1. 在AppDb中创建一个“ DOMAIN \ User1”用户,该用户使用该实例的SSMS \ Security \ Logins中未列出的“ DOMAIN \ User1”登录名。
  2. 在AppDb中创建一个“ DOMAIN \ User1”架构。
  3. 在新的“ DOMAIN \ User1”架构中使用创建这些表。

这些结果令我完全困惑。这是我的问题:

  1. 我希望表创建失败,而不是创建其他对象。有人可以指出我在联机丛书中对此进行解释的部分吗?
  2. 如果服务器要添加架构,为什么服务器不创建“ DOMAIN \ AppUsers”架构并将新表添加到该架构?
  3. 另外,数据库如何使用SSMS \ Security \ Logins中未显示的登录名?
  4. 查看SSMS \ Databases \ AppDb \ Security \ Users中的“ DOMAIN \ User1”用户,该用户图标具有一个向下的红色小箭头。这意味着什么?

为了简单起见,我们刚刚开始在首选SQL身份验证的组织中使用Windows身份验证,因此,我敢肯定,我的问题来自对这些差异的不了解。该代码是在考虑使用Windows身份验证之前编写的,因此,我确定我们需要提高对以数据库所有者以外的任何其他人身份使用Windows身份验证登录时创建新架构的理解。

如果您不知道,我就是推动使用Windows身份验证而不是SQL身份验证的人。如果我们对此没有深刻的了解,我们将恢复为SQL身份验证。


您可以为域用户定义默认架构{dbo,例如},但不能为域组定义。

Answers:


9

回到SQL Server 2000,这种情况一直存在。
如果没有架构,SQL Server如何知道您要将其放入dbo架构中?

指定默认架构的唯一方法是:

  • 使用SQL登录名(不是Windows)
  • 以“ sysadmin”身份运行

这些都不可接受

最佳实践是始终为DDL和DML的每个对象引用限定模式。由于重复使用计划,因此具有明显的性能优势。

另外,对于SQL Server 2005,故意使用架构更好:

  • 表中 Data
  • 在其他表ArchiveStaging
  • 代码在每个客户端权限模式:DesktopWebGUI

使用dbo模式是如此的千年:-)链接:


因此,我可以避免的是,我们应该更新代码以在新表之前添加模式,对吗?这是否意味着在“安全性”节点下出现新用户是常见的情况?
flipdoubt 2011年

@flipdoubt:是的。一旦进入,并将模式用作命名空间或容器,它便成为第二天性
gbn11年

最后一个问题。如果通常的做法是在对象创建过程中自动添加用户,以及在方案创建过程中指定方案的最佳做法,那么在自动创建的用户在查询新方案中的对象时会出错时,如何授予新方案的权限?使用我发布的有关“ DOMAIN \ User1”的示例,我可以将访问权限分配给“ DOMAIN \ AppUsers”帐户,但是查询将使用“ DOMAIN \ User1”或“ DOMAIN \ AppUsers”的访问权限吗?太偷偷摸摸的以至于服务器在创建对象后立即创建用户。
flipdoubt

权限将默认授予架构所有者,即user1。这就像DB_OWNER的架构
GBN

2

那么@gbn类型的速度比我做的...

我唯一提供的是...您引用用户正在登录应用程序,允许用户创建表等。如果应用程序允许这样做,并且用户没有通过SQL Server本身(使用SSMS直接登录到数据库)进行此操作,则需要与该应用程序的供应商联系。


我们编写了该应用程序。
flipdoubt

2

尽管问题很老,并且已经接受了答案,但我将尝试更具体地回答您的问题(而不是提供一般性建议)。

  1. 该行为记录在https://docs.microsoft.com/zh-cn/sql/t-sql/statements/create-schema-transact-sql的“隐式架构和用户创建”部分中

  2. 如果要在特定的架构中创建对象(当未在语句中显式指定架构时),则应为用户指定DEFAULT_SCHEMA。在SQL Server 2008 R2(及更低版本)中,如果您尝试为基于Windows组的用户分配DEFAULT_SCHEMA,则会出现错误,但在SQL Server 2012(及更高版本)中,现在可以这样做。

  3. 仅仅因为没有该用户的登录名而没有显示它。如https://docs.microsoft.com/zh-cn/sql/t-sql/statements/create-user-transact-sql中所指定的,可能会为使用其他组登录甚至没有登录的人创建用户任何登录。

  4. 红色小箭头(或在较新版本的SSMS中,红色小箭头x)表示在数据库中没有CONNECT权限的用户(但是,可以通过另一个组获得此权限)。


0

尽管这是一个老问题,但我已经观察到了此行为(在SQL Server 2014中),发现以下情况:

给定脚本

USE [master]
CREATE DATABASE [Test]

USE [Test]

-- Note that we create the users without specifying the default schema
CREATE USER [MyDomain\MyADGroup] FOR LOGIN [MyDomain\MyADGroup] -- ad group
CREATE USER [MyDomain\MyDomainUser] FOR LOGIN [MyDomain\MyDomainUser] -- ad user (not in said AD group)

ALTER ROLE db_ddladmin ADD MEMBER [MyDomain\MyADGroup]
ALTER ROLE db_ddladmin ADD MEMBER [MyDomain\MyDomainUser]

EXECUTE AS LOGIN = 'MyDomain\MyAdGroupUser' -- a windows account which is a member of [MyDomain\MyADGroup]

CREATE TABLE Test
(
    a INT
)

REVERT 

EXECUTE AS USER = 'MyDomain\MyDomainUser'

CREATE TABLE Test
(
    a INT
)

该脚本将创建两个称为Test的表。

第一个CREATE TABLE创建名为的表[MyDomain\MyAdGroupUser].[Test],还创建MyDomain\MyAdGroupUser模式(以及MyDomain\MyAdGroupUser已禁用的数据库用户)

第二个CREATE TABLE创建一个名为[dbo].[Test]

这样做的原因是因为CREATE TABLE命令没有显式声明架构,所以它们将使用默认架构。

由于我们在创建用户时未指定默认架构,因此SQL Server将Windows用户的默认架构设置为dbo,但未为Windows Group用户设置任何默认架构,因此这会导致创建架构/用户

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.