You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何使用PowerShell在Azure AD中通过用户名密码生成委派令牌?

解决Azure AD应用生成委派令牌的问题

核心修改点说明

你的原脚本创建的是应用级权限(客户端凭据令牌),要生成代表用户的委派令牌,需要从权限类型、应用配置、令牌请求三个部分调整:


1. 替换应用权限为委派类型

原脚本中Add-AzADAppPermission用了-Type Role,这是添加应用级权限。要改成委派权限,需将-Type设为Scope,同时注意委派权限的ID和应用权限不同

  • Mail.Send的委派权限ID:e1fe6dd8-ba31-4d61-89e7-88639da4683d
  • 原脚本里的b633e1c5-b582-4048-a93e-9f11b44c7e96是应用级权限ID,不能混用

2. 配置应用支持用户名密码登录

要通过用户名密码流(ROPC)获取委派令牌,需开启应用的公共客户端访问:

Set-AzADApplication -ObjectId $app.Id -AllowPublicClient $true

3. 完成管理员同意(可选但必要)

如果要让所有用户无需手动授权就能使用,需执行管理员同意委派权限的操作,替换原脚本里的New-AzADServicePrincipalAppRoleAssignment

New-AzADServicePrincipalOAuth2PermissionGrant -ClientId $sp.Id -ResourceId $graphSp.Id -Scope "Mail.Send" -ConsentType "AllPrincipals"

完整修改后的脚本

Connect-AzAccount

$appName = "MyTestingApp"
$app = New-AzADApplication -DisplayName $appName

# 开启应用支持公共客户端(适配ROPC流)
Set-AzADApplication -ObjectId $app.Id -AllowPublicClient $true

$secret = New-AzADAppCredential -ApplicationId $app.AppId -EndDate (Get-Date).AddYears(1)

Start-Sleep -Seconds 30

$graphApiId = '00000003-0000-0000-c000-000000000000'
# 使用Mail.Send的委派权限ID
$mailSendDelegatedId = 'e1fe6dd8-ba31-4d61-89e7-88639da4683d'

$graphSp = Get-AzADServicePrincipal -Filter "appId eq '$graphApiId'"

# 添加委派权限(Type设为Scope)
Add-AzADAppPermission -ObjectId $app.Id -ApiId $graphApiId -PermissionId $mailSendDelegatedId -Type Scope

Start-Sleep -Seconds 30
$sp = New-AzADServicePrincipal -ApplicationId $app.AppId

# 管理员同意该委派权限,允许所有用户使用
New-AzADServicePrincipalOAuth2PermissionGrant -ClientId $sp.Id -ResourceId $graphSp.Id -Scope "Mail.Send" -ConsentType "AllPrincipals"

Start-Sleep -Seconds 30

# 替换为目标用户的凭据
$username = "user@yourtenant.onmicrosoft.com"
$password = ConvertTo-SecureString "用户密码" -AsPlainText -Force

$tenantId = (Get-AzContext).Tenant.Id
$clientId = $app.AppId
$clientSecret = $secret.SecretText

$tokenUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"

# 使用ROPC授权类型生成委派令牌
$body = @{
    client_id     = $clientId
    client_secret = $clientSecret
    scope         = "https://graph.microsoft.com/Mail.Send offline_access"
    grant_type    = "password"
    username      = $username
    password      = $password.GetNetworkCredential().Password
}

$response = Invoke-RestMethod -Method Post -Uri $tokenUrl -ContentType "application/x-www-form-urlencoded" -Body $body
$token = $response.access_token
$token

注意事项

  • ROPC流不支持开启MFA的用户,仅适合测试场景,生产环境建议用授权码流
  • 若不需要管理员全局同意,可省略New-AzADServicePrincipalOAuth2PermissionGrant,但首次使用需要用户手动授权(ROPC流下可能报错,建议还是做管理员同意)

内容的提问来源于stack exchange,提问作者user12072310

火山引擎 最新活动