练习 - 控制谁能访问你的数据库
即使可以通过网络连接到数据库,但这并不意味着就可以实际访问数据本身。 按照分层方法,你想要确保只有需要访问数据的用户可以实际访问数据。 身份验证和授权会在此访问中发挥作用。
身份验证
身份验证是验证身份的过程。 此身份可能是用户、系统上运行的服务或者系统本身(例如虚拟机)。 通过身份验证过程,可以确保某个人员或系统与其声称的身份相符。 SQL 数据库支持两种类型的身份验证:SQL 身份验证和 Microsoft Entra 身份验证。
SQL 身份验证
SQL 身份验证方法使用用户名和密码。 可以主数据库中创建用户帐户并为其授予服务器上所有数据库的权限。 还可以在数据库本身创建用户(称为包含的用户),并给予这些用户仅访问该数据库的权限。 在为数据库创建逻辑服务器时,已指定一个包含用户名和密码的“服务器管理员”登录名。 通过这些凭据,可以使用数据库所有者(即“dbo”)的身份通过服务器上任何数据库的身份验证。
Microsoft Entra 身份验证
该身份验证方法使用 Microsoft Entra ID 管理的标识,并支持托管和集成的域。 请尽可能使用 Microsoft Entra 身份验证(集成安全性)。 通过 Microsoft Entra 身份验证,可以管理数据库用户和其他 Microsoft 服务的标识。 集中 ID 管理提供一个单一位置来管理数据库用户,并简化权限管理。 如果你要使用 Microsoft Entra 身份验证,则必须创建另一个称为“Microsoft Entra 管理员”的服务器管理员,该管理员可以管理 Microsoft Entra 用户和组。 此管理员还能执行普通服务器管理员可以执行的所有操作。
授权
授权是指标识可在 Azure SQL 数据库中执行的操作。 此授权由直接授予用户帐户和数据库角色成员身份的权限控制。 数据库角色用于将权限组合在一起,以简化管理。 将用户添加到角色,以授予角色拥有的权限。 这些权限可以包含多项能力,比如登录到数据库、读取表格以及从数据库添加和删除列。 最佳做法是,应向用户授予所需的最低权限。 向 SQL 和 Microsoft Entra 用户授权的过程是相同的。
在此处的示例中,要连接的服务器管理员帐户是 db_owner 角色的成员,该角色有权在数据库中执行任何操作。
实践中的身份验证和授权
最佳做法是,应用程序应使用专用帐户进行身份验证。 这样,便可以限制授予应用程序的权限,并在应用程序代码容易受到 SQL 注入攻击的情况下降低恶意活动的风险。 建议创建包含的数据库用户,使应用程序能够直接向数据库进行身份验证。 有关详细信息,请参阅 包含的数据库用户 - 使你的数据库可移植。
Microsoft Entra 身份验证可用于集中管理数据库用户的标识,并替代 SQL Server 身份验证。
现在看看如何设置用户并授予其对数据库的访问权限。 在此情况下,我们将针对用户使用 SQL 身份验证,但该过程实质上与 Microsoft Entra 身份验证相同。
创建数据库用户
创建可用于授予访问权限的新用户。
在 Cloud Shell 中的 appServer VM 上,以
ADMINUSER
身份再次连接到数据库。sqlcmd -S tcp:[server-name].database.windows.net,1433 -d marketplaceDb -U '[username]' -P '[password]' -N -l 30
运行以下命令来创建新用户。 此用户是“包含的用户”,仅有“商城”数据库的访问权限。 可以根据需要随意调整密码,但请务必进行记录,因为在之后的步骤中我们将需要此密码。
CREATE USER ApplicationUser WITH PASSWORD = 'YourStrongPassword1'; GO
使用这些凭据,用户将能够通过数据库身份验证,但无权访问任何数据。 让我们来授予此用户访问权限。
授予用户权限
让我们把用户设置为 db_datareader
和 db_datawriter
角色的成员,分别授予对数据库的读取和写入权限。 还想阻止此用户访问带有地址的表格。
仍与 appServer 上的
sqlcmd
连接时,运行以下 T-SQL 为你刚才创建的用户授予db_datareader
和db_datawriter
角色。ALTER ROLE db_datareader ADD MEMBER ApplicationUser; ALTER ROLE db_datawriter ADD MEMBER ApplicationUser; GO
可以进一步缩小访问范围。 可以使用 DENY 运算符拒绝用户访问数据库中的其他元素。 运行以下 T-SQL 以拒绝用户“ApplicationUser”从
SalesLT.Address
表中选择数据。DENY SELECT ON SalesLT.Address TO ApplicationUser; GO
现在让我们以该用户的身份登录,并亲自查看此配置。
仍在 T-SQL 提示符处时,输入
exit
退出会话。现在以刚创建的用户身份重新登录到数据库。
sqlcmd -S tcp:[server-name].database.windows.net,1433 -d marketplaceDb -U 'ApplicationUser' -P '[password]' -N -l 30
运行以下查询。 该查询从用户有权访问的表中拉取数据。
SELECT FirstName, LastName, EmailAddress, Phone FROM SalesLT.Customer; GO
你应该会得到一份客户列表。
FirstName LastName EmailAddress Phone -------------- -------------- ------------------------------- ------------ Orlando Gee orlando0@adventure-works.com 245-555-0173 Keith Harris keith0@adventure-works.com 170-555-0127 Donna Carreras donna0@adventure-works.com 279-555-0130 Janet Gates janet1@adventure-works.com 710-555-0173 ...
看一看当尝试查询无权访问的表格时,会发生什么情况。
SELECT * FROM SalesLT.Address; GO
应该会收到你无权访问此表格的消息。
Msg 229, Level 14, State 5, Server server-22942, Line 1 The SELECT permission was denied on the object 'Address', database 'marketplace', schema 'SalesLT'.
此处可以看到,即使已经授予了对数据库的读/写访问权限,但通过显式拒绝对表的访问,还可以进一步保护对数据的访问。 如果有多个用户共享类似访问权限,可创建具有适当权限的自定义角色,并简化管理。
务必正确保护数据库,并仅在必要时才授予访问权限。 Azure SQL 数据库提供内置功能,以完全控制进行身份验证和授权身份访问数据库中数据的功能。