使用包含的数据库实现数据库可移植

适用于: SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics

使用包含的数据库用户在数据库级别对 SQL Server 和 Azure SQL 数据库连接进行身份验证。 包含的数据库是独立于其他数据库以及托管数据库的 SQL Server 或 SQL 数据库实例(以及 master 数据库)的一种数据库。

SQL Server 支持包含的数据库用户进行 Windows 和 SQL Server 身份验证。 使用 SQL 数据库时,将包含的数据库用户与数据库级别防火墙规则相结合。

本文介绍与传统登录/用户模型和 Windows 或服务器级别防火墙规则相比,使用包含的数据库模型的好处。 在特定场景下,可管理性或应用程序业务逻辑可能仍然需要使用传统登录/用户模型和服务器级别防火墙规则。

传统登录和用户模型

在传统的连接模型中,通过提供由 Windows 进行身份验证的用户或组凭据,Windows 用户或 Windows 组成员可连接到数据库引擎。 用户也可以同时提供名称和密码,并通过使用 SQL Server 身份验证进行连接。 在这两种情况下,master 数据库必须拥有匹配连接凭据的登录名。

在数据库引擎确认了 Windows 身份验证凭据或验证了 SQL Server 身份验证凭据之后,该连接通常会尝试连接到用户数据库。 若要连接到某个用户数据库,登录名必须映射到(即关联)用户数据库中的某个数据库用户。 连接字符串还可以指定连接到特定数据库,该数据库在 SQL Server 中为可选但在 SQL 数据库中为必需。

重要原则是登录(在 master 数据库中)和用户(在用户数据库中)必须存在,并且彼此相关。 与用户数据库的连接依赖于 master 数据库中的登录。 此依赖关系限制了数据库移动到其他托管 SQL Server 实例或 Azure SQL 数据库服务器的能力。

如果到 master 数据库的连接不可用(例如,进程中出现故障),整个连接时间将会增加,或者连接可能超时。连接不可用可能会降低连接可伸缩性。

包含的数据库用户模型

在包含的数据库用户模型中,master 数据库中不存在登录。 相反,身份验证过程发生在用户数据库中。 用户数据库中的数据库用户在 master 数据库中没有关联的登录。

包含的数据库用户模型支持 Windows 身份验证和 SQL Server 身份验证。 在 SQL Server 和 SQL 数据库中均可使用。

要作为包含的数据库用户进行连接,连接字符串必须始终包含用户数据库的参数。 数据库引擎使用此参数了解哪个数据库负责管理身份验证过程。

包含的数据库用户的活动仅限于身份验证数据库。 必须在用户所需的每个数据库中独立创建数据库用户帐户。 若要更改数据库,SQL 数据库用户必须创建一个新的连接。 如果另一个数据库中存在相同的用户,SQL Server 中的包含的数据库用户可以更改数据库。

在 Azure 中,SQL 数据库和 Azure Synapse Analytics 支持将 Microsoft Entra ID(以前称为 Azure Active Directory)标识为包含的数据库用户。 SQL 数据库支持使用 SQL Server 身份验证的包含的数据库用户,但 Azure Synapse Analytics 不支持。 有关更多信息,请参阅“使用 Microsoft Entra 身份验证连接到 SQL 数据库”。

使用 Microsoft Entra 身份验证时,用户可以使用 Microsoft Entra 通用身份验证从 SQL Server Management Studio 进行连接。 管理员将通用身份验证配置为需要多重身份验证,这会使用电话呼叫、短信、PIN 智能卡或移动应用通知来验证身份。 有关更多信息,请参阅“使用 Microsoft Entra 多重身份验证”。

对于 SQL 数据库 和 Azure Synapse Analytics,连接字符串中始终需要数据库名称。 因此,从传统模型切换到包含的数据库用户模型时,无需更改连接字符串。 对于 SQL Server 连接,如果数据库名称尚不存在,必须添加到连接字符串。

重要

使用传统模型时,服务器级别角色和服务器级别权限可以限制访问所有数据库。 使用包含的数据库模型时,数据库所有者和具有 ALTER ANY USER 权限的数据库用户可以允许访问数据库。 此权限减少了高特权服务器登录的访问控制,并且使访问控制扩大至将高特权数据库用户包含在内。

防火墙

SQL Server

对于 SQL Server,Windows 防火墙规则适用于所有连接,并且对登录(传统模型连接)和包含的数据库用户具有相同影响。 有关 Windows 防火墙的更多信息,请参阅“为数据库引擎访问配置 Windows 防火墙”。

SQL 数据库防火墙

SQL 数据库允许服务器级连接(登录)和数据库级连接(包含的数据库用户)使用单独的防火墙规则。 SQL 数据库连接到用户数据库时,会首先检查数据库防火墙规则。 如果没有允许访问数据库的规则,SQL 数据库会检查服务器级防火墙规则。 检查服务器级防火墙规则需要访问 SQL 数据库服务器的 master 数据库。

与包含的数据库用户相结合的数据库级防火墙规则可无需在连接过程中访问服务器的 master 数据库。 结果是提高了连接的可伸缩性。

有关 SQL 数据库防火墙规则的详细信息,请参阅以下主题:

语法差异

传统模型 包含的数据库用户模型
连接到 master 数据库时:

CREATE LOGIN login_name WITH PASSWORD = 'strong_password';

随后连接到用户数据库时:

CREATE USER 'user_name' FOR LOGIN 'login_name';
连接到用户数据库时:

CREATE USER user_name WITH PASSWORD = 'strong_password';
传统模型 包含的数据库用户模型
要在 master 数据库的上下文中更改密码:

ALTER LOGIN login_name WITH PASSWORD = 'strong_password';
要在用户数据库的上下文中更改密码:

ALTER USER user_name WITH PASSWORD = 'strong_password';

SQL 托管实例

在包含的数据库的上下文中,Azure SQL 托管实例的行为与本地 SQL Server 的类似。 创建包含的用户时,请确保将数据库的上下文从 master 数据库更改为用户数据库。 此外,在设置包含选项时,不应与用户数据库建立活动连接。 使用以下代码作为指南。

警告

以下示例脚本使用 kill 语句关闭数据库中的所有用户进程。 运行此脚本前,请确保了解此脚本的影响以及是否适合你的业务。 此外,请确保SQL 托管实例数据库上没有其他连接处于活动状态,因为此脚本将中断数据库上运行的其他进程。

USE master;

SELECT * FROM sys.dm_exec_sessions
WHERE database_id  = db_id('Test')

DECLARE @kill_string varchar(8000) = '';
SELECT @kill_string = @kill_string + 'KILL ' + str(session_id) + '; '  
FROM sys.dm_exec_sessions
WHERE database_id  = db_id('Test') and is_user_process = 1;

EXEC(@kill_string);
GO

sp_configure 'contained database authentication', 1;  
GO
 
RECONFIGURE;  
GO 

SELECT * FROM sys.dm_exec_sessions
WHERE database_id  = db_id('Test')

ALTER DATABASE Test
SET containment=partial

USE Test;  
GO 

CREATE USER Carlo  
WITH PASSWORD='Enterpwdhere*'  

SELECT containment_desc FROM sys.databases
WHERE name='Test'

注解

  • 必须为每个 SQL Server 实例启用包含的数据库用户。 有关更多信息,请参阅“包含的数据库身份验证(服务器配置选项)”。
  • 具有非重叠名称的包含的数据库用户和登录可以在应用程序中共存。
  • 假设 master 数据库中的登录名为“name1”。 如果创建一个名为“name1”的包含的数据库用户,在连接字符串中提供数据库名称时,将选择数据库用户的上下文而非登录上下文,来连接到数据库。 即包含的数据库用户将优先于具有相同名称的登录。
  • 在 SQL 数据库中,包含的数据库用户的名称不能与服务器管理员帐户的名称相同。
  • SQL 数据库服务器管理员帐户绝不能是包含的数据库用户。 服务器管理员具有足够的权限来创建和管理包含的数据库用户。 服务器管理员可以向包含的数据库用户授予针对用户数据库的权限。
  • 由于包含的数据库用户是数据库级主体,因此需要在每个要使用的数据库中创建包含的数据库用户。 标识仅限于数据库。 标识在所有方面都独立于同一台服务器上其他数据库中具有相同名称和相同密码的用户。
  • 使用通常用于登录的相同强度的密码。