通过 powershell 以编程方式使用 MFA 对 AAD 进行身份验证

Programmatically authenticate into AAD with MFA via powershell

我有一个 PowerShell 脚本,它使用用户凭据通过命令 Connect-AzAccount 登录到 Azure 订阅。

代码如下:

$userPassword='password'
$userName="username"
$tenantId="########-####-####-####-############"
$subscriptionId="########-####-####-####-############"
$azureSecpassword = $userPassword | ConvertTo-SecureString -asPlainText -Force
$azureCredential = New-Object System.Management.Automation.PSCredential($userName, $azureSecpassword)
Connect-AzAccount -Credential $azureCredential -Tenant $tenantId -SubscriptionId $subscriptionId

以上代码无需任何用户交互即可运行。

几天前,客户为用户启用了多重身份验证。 如何通过多重身份验证保持完全自动化的登录过程(无需用户交互)?

此致。

这是一个常见问题。不幸的是,答案是否定的。如果该帐户启用了 MFA,您可以使用交互式方式登录。

在这种情况下,我们一般选择使用服务主体非交互登录。

$azureAplicationId ="Azure AD Application Id"
$azureTenantId= "Your Tenant Id"
$azurePassword = ConvertTo-SecureString "client secret" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId  -ServicePrincipal 

参考 - Sign in with a service principal.

如果您必须以用户身份登录,可能有两种可选方法。

1。如果您将 运行 本地或特定 PC 中的脚本

您可以Persist Azure user credentials. You can enable auto save,或者手动将上下文保存到文件中,然后在另一个 PS 会话中使用它。

如果开启了自动保存,则可以直接获取上下文如下:

Get-AzContext

# If you have more than one contexts, you can choose one by specifing the name
Get-AzContext -Name 'CSP Azure (e5b0****-****-****-****-5e5f****4c68) - jack@h****a.onmicrosoft.com'

如果您想手动执行,这里是示例:

# Interactively log for one time
Connect-AzAccount

# Save the context
Save-AzContext -Path D:\ctx.dat

在另一个 PS 会话中,您可以:

Import-AzContext -Path D:\ctx.dat

2。使用刷新令牌获取令牌,并连接到 Azure

您可以从自动保存的 Azure 上下文中获取刷新令牌(通常在 C:\Users\<UserName>\.Azure\TokenCache.dat)。

用记事本打开dat文件,你会得到刷新令牌:

然后您可以使用该刷新令牌在 PowerShell 中获取一个新令牌,并连接到 Azure:

Clear-AzContext
$tenantId = "e4c9ab4e-****-****-****-230b****57fb"
$subscriptionId = "e5b0fcfa-****-****-****-5e5f****4c68"
$refreshToken = 'AQABAAAAAAAP0****a lot of characters here*****0A9FWoB8mvDtoWRJHBVO7GJzodLKYmNIAA'
$url = "https://login.microsoftonline.com/" + $tenantId + "/oauth2/token"
$body = "grant_type=refresh_token&refresh_token=" + $refreshToken
$response = Invoke-RestMethod $url -Method POST -Body $body
$AccessToken = $response.access_token

Connect-AzAccount -AccountId "the user id, jack@h****a.onmicrosoft.com" -AccessToken $AccessToken -Tenant $tenantId -SubscriptionId $subscriptionId

How can I keep a fully automated login process (without user interactions) with the multi-factor authentication?

您不能使用用户帐户执行此操作——这就是多重​​身份验证的全部意义所在。

相反,Azure AD 支持使用 service 主体进行身份验证(而不是 user 主体,就像您当前所做的那样), Azure 支持向服务主体授予对 Azure 资源的访问权限。

MFA 要求(和其他条件访问策略)不适用于服务主体(通常称为 Azure AD "app"),服务主体支持更安全的自动化方案身份验证方法(例如 public/private 密钥对).

那么,你应该怎么做:

  1. 确保机器运行此脚本是安全的。任何有权访问该机器的人都具有与脚本相同的访问权限。

  2. 创建应用程序身份并将凭据与其相关联。

    Note: It is strongly recommend you use certificate-based authentication for your service principal, instead of password-based. It is a very insecure practice to have any kind of secret stored in a PowerShell script!

  3. 授予服务主体对 Azure 资源的最低访问级别,以允许其完成所需的任务。

  4. 更新您的脚本以使用应用程序的身份(服务主体)而不是用户的身份。它比使用用户帐户更简单:

    $tenantId = "########-####-####-####-############"
    
    $subscriptionId = "########-####-####-####-############"
    $appId = "########-####-####-####-############"
    $thumbprint= "##############"
    Connect-AzAccount -ServicePrincipal -TenantId $tenantId -ApplicationId $appId -CertificateThumbprint $thumbprint
    

注意:如果此脚本在 Azure 的虚拟机上 运行,您应该忘记第 2 步,只需启用 managed identity and use that.