当你需要使用脚本和工具在Azure中自动化任务时,你会考虑使用服务帐户还是Azure服务主体吗?对于一些人来说,创建一个新的服务帐户,赋予它所需的所有管理员角色,并排除它免受多因素身份验证的影响,这并不罕见。
I know what you’re thinking – “that is a horrible idea”. Of course, it is! And for sure, your IT Sec will give you a lot of grief if you did all that.
但是,还有什么替代方案呢?如何使用具有有限范围的特权凭据,而无需从多因素身份验证中排除它呢?幸运的是,这正是本文将教给你的。
在本文中,你将了解到Azure服务主体是什么。你将学会如何使用不同类型的凭据(如密码、密钥和证书)创建服务主体。
有许多工具可以创建Azure服务主体,包括使用Azure门户、Azure Active Directory管理中心、Azure AD PowerShell、Azure CLI和Azure PowerShell。本文将重点介绍Azure PowerShell这个工具。
还感兴趣吗?继续阅读,让我们开始吧!
要求
由于这是一篇实践学习的文章,以下是一些前提条件,以便您能跟上。
- 访问Azure订阅。最好是在测试租户上进行操作。如果您没有,您可以注册免费试用。
- 访问运行Windows 10并具有PowerShell 5.1的计算机。
- 必须安装Azure PowerShell模块。
Azure服务主体与服务帐户
自动化工具和脚本通常需要管理员或特权访问权限。比如,提供存储账户或按计划启动和停止虚拟机。大多数管理员可能会使用完全特权的用户帐户(称为服务帐户)来设置脚本的凭据要求。
A service account is essentially a privileged user account used to authenticate using a username and password. And, if used with automation, a service account is most likely excluded from any conditional access policies or multi-factor authentication.
另一方面,Azure服务主体可以设置为使用用户名和密码或证书进行身份验证。将其视为一个没有用户的用户身份,而是应用程序的身份。
Azure服务主体可以被分配到足够少的访问权限,仅限于一个特定的单一Azure资源。例如,您可以创建一个具有基于角色的访问权限的Azure服务主体,该权限适用于整个订阅或仅限于单个Azure虚拟机。
创建 Azure 服务主体的主要考虑因素
在创建 Azure 服务主体之前,您应该了解需要计划的基本细节。这些细节可能看起来很简单,但它们将使创建 Azure 服务主体变得尽可能高效和简单。
显示名称。一切都从名称开始,Azure 服务主体必须有一个名称。这里没有规则,但您的组织可能有一个规定的命名约定。
- 要使用的凭据类型。您可以选择创建将使用密码或证书进行身份验证的 Azure 服务主体。这并不意味着您只能选择其中一种,您可以同时使用两者。
对于服务主体,用户名和密码更适当地称为应用程序 ID 和密钥。
- 凭据的有效期。无论您分配密码还是证书凭据,都必须为其有效性定义开始和结束日期。凭据的有效期通常取决于您愿意多频繁地轮换/更新证书和密码。
- 访问范围。您是否正在创建将访问订阅、资源组或选择资源的 Azure 服务主体?
- 角色。有几种可用的角色,例如 Contributor、Reader 和 Owner,等等。您需要定义哪个角色是服务主体的“足够”角色。
创建具有自动分配密钥的Azure服务主体
在Azure中创建新服务主体的核心是使用New-AzAdServicePrincipal
cmdlet。在此示例中,将使用以下值创建新服务主体:
DisplayName: AzVM_Reader
Scope: AzVM1 (虚拟机)
Role: Reader
Password: <自动分配>
Credential Validity: 1 年
获取目标范围(虚拟机)的 ID
正如您所看到的,此新服务主体的范围仅限于名为AzVM1的虚拟机。但是,-Scope
参数不仅仅接受名称,还需要资源的整个ID。因此,在此示例中,首先要获取的是AzVM1虚拟机的ID。为此,请使用以下代码。
在PowerShell中运行上述代码时,您应该看到虚拟机名称和ID的列表,类似于下面的屏幕截图。

使用秘密密钥创建Azure服务主体
现在您已经有了目标范围(即AzVM1虚拟机的ID),可以使用以下命令创建具有reader角色的新服务主体,并将新服务主体的属性存储在$sp
变量中。
由于上述命令,服务主体已创建并具有以下值。

解密秘密密钥
现在您拥有ApplicationID和Secret,这是服务主体的用户名和密码。但是,Secret的值显示为System.Security.SecureString。您可能想知道密码是什么。为此,请使用以下命令将密码转换为纯文本。
上述命令将$sp.Secret
的安全字符串值转换为纯文本。参见下面的图片作为参考。

验证Azure服务主体角色分配
如何知道这是否起作用?您可以使用Azure门户检查资源的访问控制列表。例如,在下面的图片中,您可以看到AzVM_Reader服务主体现在对AzVM1虚拟机具有读取者访问权限。

此外,您还可以使用Get-AzRoleAssignment -ObjectID $sp.id
命令获取Azure服务主体的角色分配。请参见下面的截图示例。

创建具有密码的Azure服务主体
如果您想更好地控制分配给Azure服务主体的密码或密钥,请在创建服务主体时使用-PasswordCredential
参数。如果密码必须符合复杂性要求,则特别有用。
在此示例中,将使用以下值创建新的Azure服务主体:
显示名称: ATA_RG_Contributor
范围: ATA (资源组)
角色: 贡献者
密码: 20个字符长,包含6个非字母数字字符
凭证有效期: 5年
获取目标范围(资源组)的ID
这个新的服务主体的范围涵盖了名为ATA的整个资源组。首先要获取的是ATA资源组的ID。为此,请使用下面的代码,确保将-Name
参数的值更改为您的资源组名称。
然后,您应该看到现在存储在$Scope
变量中的资源组的ResourceID
。

生成密码字符串
下一步是生成符合20个字符长,包含6个非字母数字字符复杂性的密码。为此,您可以利用.NET静态方法GeneratePassword()
。
在上面的代码GeneratePassword(20, 6)
中,第一个值表示密码的长度,第二个值表示要包含的非字母数字字符的数量。结果显示在下面的截图中。

GeneratePassword()
static method创建密码凭证对象
现在您已经有了密码字符串,下一步是创建Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential
对象。此对象将包含存储在$password
变量中的密码字符串和有效期为5年。复制下面的代码并在您的Azure PowerShell会话中运行它。
在PowerShell中运行上述代码将把凭据对象存储到$PasswordCredential
变量中。预期的结果应类似于下面所示的内容。

创建带有密码的服务主体
现在您已经准备好创建Azure服务主体所需的参数值了。下面的代码将创建显示名称为ATA_RG_Contributor的服务主体,并使用存储在$PasswordCredential
变量中的密码。
运行代码后,新的服务主体应该已经创建,并且属性存储在$sp
变量中。请参阅下面的示例结果。

分配角色和范围
在上一节中已经创建了Azure服务主体,但是没有角色和范围。这是因为-Role
和-Scope
参数不能与-PasswordCredential
参数一起使用。这意味着需要额外的步骤来将角色和范围分配给服务主体。
下面的代码使用 New-AzRoleAssignment
cmdlet 来分配 Azure 服务主体的范围和角色。
下面的截图显示了在将角色和范围分配给 Azure 服务主体后的预期结果。

始终确保保存服务主体的密码,因为如果您无法保存或忘记密码,将无法恢复它。
使用服务主体密码连接到 Azure
现在要开始使用服务主体了。与使用用户帐户登录 Azure PowerShell 不同,下面的代码使用服务主体凭据。
在运行以上代码后,您应该使用ATA_RG_Contributor服务主体和密码凭据登录到 Azure PowerShell。

使用证书创建 Azure 服务主体
除了密码凭据外,Azure 服务主体还可以具有基于证书的凭据。相关的证书可以是由证书颁发机构颁发的,也可以是自签名的。
在此示例中,新的 Azure 服务主体将以以下值创建:
显示名称: VSE3_SUB_OWNER
范围: VSE3(订阅)
角色: 所有者
证书有效期: 2 年
获取目标范围(订阅)的 ID
这个新服务主体的范围涵盖名为VSE3的 Azure 订阅。首先要获取的是VSE3订阅的 ID。为此,请使用下面的代码,但确保将-SubscriptionName
参数的值更改为您的资源组名称。
接下来,指定要创建的新 Azure 服务主体和自签名证书的名称。
创建自签名证书
以下代码在个人证书存储中创建了自签名密码,名称为CN=VSE3_SUB_OWNER。证书的有效期设置为两年。证书的属性保存到$cert
变量中。
下面的截图显示证书已创建。

如果你想在更熟悉的视图(GUI)中查看新证书,可以在证书控制台(certmgr.mmc)中找到它。参考下面显示的证书图像。

接下来是获取自签名证书的Base64编码值,并将其保存到$keyValue
变量中。
创建带证书的服务主体
现在证书已创建,下一步是创建新的Azure服务主体。以下代码将创建使用自签名证书作为凭据的Azure服务主体。凭据有效期与证书的有效期相吻合。
你将获得类似的输出,如下图所示。

分配角色和范围
Azure服务主体已创建,但尚未分配角色和范围。这意味着需要额外的步骤来为服务主体分配角色和范围。
下面的代码使用New-AzRoleAssignment
cmdlet将所有者角色分配给服务主体的VSE3订阅。
当运行代码时,下面的截图显示确认已完成角色分配。

使用服务主体证书连接到Azure
现在您已经创建了具有基于证书的凭据的服务主体。这意味着您可以使用它连接到Azure,而无需使用密码。相反,您将使用计算机中可用的证书作为身份验证方法。
在此示例中,服务主体的显示名称为VSE3_SUB_OWNER,证书名称为CN=VSE3_SUB_OWNER。下面的代码将从个人证书存储中获取证书的指纹,并将其用作登录凭据。
下面的截图显示,使用上述代码,仅使用ApplicationID、Tenant和证书指纹即可成功登录到Azure PowerShell。

结论
Azure服务主体是创建用于自动化任务和访问Azure资源的工具的凭据时必须考虑的安全主体。可以选择要应用的范围和角色,以提供”刚好足够”的访问权限。
在本文中,您已经学会了如何使用 PowerShell 创建 Azure 服务主体。Azure 服务主体可以具有密码、密钥或基于证书的凭据。这些凭据类型各有其优势和适用场景。
具有密码或密钥凭据的服务主体更具可移植性,但因凭据可以以明文形式共享而被认为安全性较低。另一方面,基于证书的凭据是更安全的选项,但需要更多的维护工作。
您在本文中学到的技术仅涵盖了基础知识,帮助您开始在自动化中使用 Azure 服务主体。还有许多其他配置 Azure 服务主体的方法,例如添加、删除和重置凭据。您可以在使用过程中逐步发现它们。
感谢您的阅读!
额外学习资源
以下是一些可能有助于补充本文的资源。
Source:
https://adamtheautomator.com/azure-service-principal/