我正在尝试使用c#应用程序中的Powershell命令授予对Azure Active Directory应用程序的权限。 首先,我尝试在Powershell中使用以下脚本。
Runspace runspace2 = RunspaceFactory.CreateRunspace();
runspace2.Open();
Pipeline pl = runspace2.CreatePipeline();
pl.Commands.AddScript("Function Grant-OAuth2PermissionsToApp{ \n" +
"$azureAppId = '" + appID + "'; \n" +
"$username = '<login id >'; \n" +
"$password = convertTo-securestring '<password>' -AsPlainText -Force; \n" +
"$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password; \n" +
"$res = login-azurermaccount -Credential $cred; \n" +
"$context = Get-AzureRmContext; \n" +
"$tenantId = $context.Tenant.Id; \n" +
"$refreshToken = @($context.TokenCache.ReadItems() | where {$_.tenantId -eq $tenantId -and $_.ExpiresOn -gt (Get-Date)})[0].RefreshToken; \n" +
"$body = 'grant_type=refresh_token&refresh_token=$($refreshToken)&resource=\"74658136-14ec-4630-ad9b-26e160ff0fc6\"'; \n" +
"$apiToken = Invoke-RestMethod 'https://login.windows.net/$tenantId/oauth2/authorize?client_id=$azureAppId&response_type=code&&redirect_uri=https%3A%2F%2FPowerBiApp.contoso.com&response_mode=query' -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded'; \n" +
"$header = @{ \n" +
"'Authorization'='Bearer '+$apiToken.access_token; \n" +
"'X-Requested-With'='XMLHttpRequest'; \n" +
"'x-ms-client-request-id'=[guid]::NewGuid(); \n" +
"'x-ms-correlation-id'=[guid]::NewGuid(); \n" +
"}; \n" +
"$url = 'https://main.iam.ad.ext.azure.com/api/RegisteredApplications/$azureAppId/Consent?onBehalfOfAll=true'; \n" +
"Invoke-RestMethod -Uri $url -Headers $header -Method POST -ErrorAction Stop; \n" +
"}");
pl.Commands.AddScript("Grant-OAuth2PermissionsToApp");
var r = pl.Invoke();
此代码授予了Azure AD注册应用程序的权限。 我修改了此脚本以在C#应用程序中运行它。
$refreshToken
这给了我解析错误-刷新令牌格式错误或无效。 我尝试了以下方法来获得解决方案:
$refreshtoken = $refreshtoken.Split(''n')[0];
的值后,在代码中使用尝试拆分字符串,以便如果我两次获得令牌字符串,则只能选择一个。
-AsPlainText
我发现在https://login.microsoftonline.com/{tenant}/oauth2/authorize?client_id=<ApplicationId>&response_type=code&&redirect_uri=<Application redirect Url>&response_mode=query
之类的Powershell脚本中使用的“-”可能会更改为endash。我重新检查了脚本中使用的所有“-”。
另一个解决方案是我发现,当我们尝试使用原始数据获取刷新令牌时,应使用以下url和参数。我从site
获得此网址{{1}}
这些我尝试过的所有方法都无效。 是否有解决此问题的适当方法? 还是还有其他方法可以获取RefreshToken来授予权限?
答案 0 :(得分:1)
我认为根本原因是由于某些Powershell脚本未正确转换为C#代码。
我在c#代码中设置了一个断点,并获取了生成的powershell脚本,然后将其与原始的powershell脚本进行比较。 c#中的某些脚本用单引号括起来,但是在原始的Powershell中,它用双引号括起来,这可能会导致一些错误。
例如,在原始的Powershell中,以下代码行:$body = "grant_type=refresh_token&refresh_token=$($refreshToken)&resource=74658136-14ec-4630-ad9b-26e160ff0fc6"
,但是在您的c#代码中(设置断点以获取值),它用单引号括起来,例如$body ='grant_type=refresh_token&refresh_token=$($refreshToken)&resource="74658136-14ec-4630-ad9b-26e160ff0fc6"'
。
因此,请在您的c#代码处设置一个断点,并从c#中获取生成的powershell脚本,并确保它与原始的powershell脚本相同。
根据比较,您的c#代码中需要更改3行,您可以将相应的行替换为以下行:
"$body = \"grant_type=refresh_token&refresh_token=$($refreshToken)&resource=74658136-14ec-4630-ad9b-26e160ff0fc6\"; \n" +
"$apiToken = Invoke-RestMethod \"https://login.windows.net/$tenantId/oauth2/authorize?client_id=$azureAppId&response_type=code&&redirect_uri=https%3A%2F%2FPowerBiApp.contoso.com&response_mode=query\" -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded'; \n" +
"$url = \"https://main.iam.ad.ext.azure.com/api/RegisteredApplications/$azureAppId/Consent?onBehalfOfAll=true\"; \n" +
希望有帮助。
从c#代码获取生成的ps脚本: