你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

具有非唯一显示名称的 Microsoft Entra 登录名和用户

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

在 Azure SQL 中创建登录名或用户时,将服务主体与 Microsoft Entra ID 中不唯一的显示名称结合使用将会导致错误。 例如,如果应用程序 myapp 不是唯一的,则执行下列 T-SQL 语句时可能会遇到以下错误:

CREATE LOGIN [myapp] FROM EXTERNAL PROVIDER 
Msg 33131, Level 16, State 1, Line 4 
Principal 'myapp' has a duplicate display name. Make the display name unique in Azure Active Directory and execute this statement again. 

WITH OBJECT_ID 扩展

发生此错误的原因是 Microsoft Entra ID 允许 Microsoft Entra 应用程序(服务主体)使用重复的显示名称,而 Azure SQL 需要唯一的名称来创建 Microsoft Entra 登录名和用户。 为了缓解此问题,用于创建登录名和用户的数据定义语言 (DDL) 语句已扩展为包含具有 WITH OBJECT_ID 子句的 Azure 资源的对象 ID。

注意

WITH OBJECT_ID 扩展当前为“公共预览版”

Microsoft Entra ID 中的大多数非唯一显示名称都与服务主体相关,但有时组名称也可能不唯一。 Microsoft Entra 用户主体名称是唯一的,因为两个用户不能具有同样的用户主体。 但是,可以使用与用户主体名称相同的显示名称来创建应用注册(服务主体)。

如果服务主体显示名称不是重复的名称,则应使用默认的 CREATE LOGINCREATE USER 语句。 WITH OBJECT_ID 扩展为公共预览版,并且是一个故障排除修复项,用于非唯一服务主体。 不需要将其与唯一的服务主体一起使用。 将 WITH OBJECT_ID 扩展用于服务主体而不添加后缀将成功运行,但是为哪个服务主体创建登录名或用户并不明显。 建议使用后缀创建别名,以唯一标识服务主体。 SQL Server 不支持 WITH OBJECT_ID 扩展。

T-SQL 为非唯一的显示名称创建登录名/用户语法

CREATE LOGIN [login_name] FROM EXTERNAL PROVIDER 
  WITH OBJECT_ID = 'objectid'
CREATE USER [user_name] FROM EXTERNAL PROVIDER 
  WITH OBJECT_ID = 'objectid'

通过 T-SQL DDL 扩展来使用对象 ID 创建登录名或用户时,可以避免错误 33131,并且还可以为使用对象 ID 创建的登录名或用户指定别名。 例如,以下项将使用应用程序对象 ID 4466e2f8-0fea-4c61-a470-xxxxxxxxxxxx 创建登录名 myapp4466e

CREATE LOGIN [myapp4466e] FROM EXTERNAL PROVIDER 
  WITH OBJECT_ID = '4466e2f8-0fea-4c61-a470-xxxxxxxxxxxx' 
  • 要执行上述查询,指定的对象 ID 必须存在于 Azure SQL 资源所在的 Microsoft Entra 租户中。 否则,CREATE 命令将失败,并显示错误消息:Msg 37545, Level 16, State 1, Line 1 '' is not a valid object id for '' or you do not have permission.
  • 使用 CREATE LOGINCREATE USER 语句时,登录名或用户名必须包含由用户定义的后缀扩展的原始服务主体名称。 作为最佳做法,后缀可以包含其对象 ID 的初始部分。 例如,对于对象 ID 2ba6c0a3-cda4-4878-a5ca-xxxxxxxxxxxxmyapp2ba6c。 但是,你还可以定义自定义后缀。 不需要通过对象 ID 形成后缀。

建议使用此命名约定将数据库用户或登录名显式关联回 Microsoft Entra ID 中的对象。

注意

该别名遵循 sysname 的 T-SQL 规范,包括最大长度为 128 个字符。 我们建议将后缀限制为对象 ID 的前 5 个字符。

Microsoft Entra ID 中服务主体的显示名称不会同步到数据库登录名或者用户别名。 在 Azure 门户中运行 CREATE LOGINCREATE USER 不会对显示名称产生影响。 同样,修改 Microsoft Entra ID 显示名称也不会影响数据库登录名或者用户别名。

标识为应用程序所创建的用户

对于非唯一服务主体,请务必验证 Microsoft Entra 别名是否已绑定到正确的应用程序。 要检查是否为正确的服务主体(应用程序)创建了用户:

  1. 从 SQL 数据库中创建的用户处获取应用程序的应用程序 ID 或 Microsoft Entra 组的对象 ID。 请参见以下查询:

    • 要从创建的用户处获取服务主体的应用程序 ID,请执行以下查询:

      SELECT CAST(sid as uniqueidentifier) ApplicationID, create_date FROM sys.server_principals WHERE NAME = 'myapp2ba6c' 
      

      示例输出:

      Screenshot of SSMS output for the Application ID.

      应用程序 ID 从指定登录名或用户名的安全标识号 (SID) 转换而来,我们可以通过执行以下查询并比较最后几个数字和创建日期来进行确认:

      SELECT SID, create_date FROM sys.server_principals WHERE NAME = 'myapp2ba6c' 
      

      示例输出:

      Screenshot of SSMS output for the SID of the application.

    • 要从创建的用户处获取 Microsoft Entra 组的对象 ID,请执行以下查询:

      SELECT CAST(sid as uniqueidentifier) ObjectID, createdate FROM sys.sysusers WHERE NAME = 'myappgroupd3451b' 
      

      示例输出:

      Screenshot of SSMS output for the Object ID of the Microsoft Entra group.

      要从创建的用户处检查 Microsoft Entra 组的 SID,请执行以下查询:

      SELECT SID, createdate FROM sys.sysusers WHERE NAME = 'myappgroupd3451b' 
      

      示例输出:

      Screenshot of SSMS output for the SID of the group.

    • 要使用 PowerShell 获取应用程序的对象 ID 和应用程序 ID,请执行以下命令:

      Get-AzADApplication -DisplayName "myapp2ba6c"
      
  2. 转到 Azure 门户,在企业应用程序或 Microsoft Entra 组资源中,分别检查应用程序 ID对象 ID。 查看它是否与从上述查询中获取的查询匹配。

注意

从服务主体创建用户时,将 WITH OBJECT_ID 子句与 CREATE T-SQL 语句一起使用时,需要对象 ID。 这与你尝试验证 Azure SQL 中的别名时所返回的应用程序 ID 不同。 使用此验证过程,你可以标识与 Microsoft Entra ID 中的 SQL 别名关联的服务主体或组,并在使用对象 ID 创建登录名或用户时防止可能出现错误。

查找正确的对象 ID

有关服务主体的对象 ID 的信息,请参阅服务主体对象。 你可以在“企业应用程序”下的 Azure 门户中找到应用程序名称旁列出的服务主体的对象 ID。

警告

在“应用注册”概述页中获取的对象 ID 不同于在“企业应用程序”概述页中获取的对象 ID。 如果你位于“应用注册”概述页中,请选择关联的本地目录中的托管应用程序的应用程序名称,以导航至“企业应用程序”概述页上正确的对象 ID。