Я пытаюсь запустить сценарий powershell в приложении C # для предоставления разрешения в приложении Azure AD, он работает в Powershell, но не в приложении C # - PullRequest
0 голосов
/ 04 января 2019

Я пытаюсь предоставить разрешения для приложения Azure Active Directory с помощью команд Powershell в приложении c #.Сначала я попробовал использовать приведенный ниже скрипт в powershell.

Function Grant-OAuth2PermissionsToApp{
Param(
    [Parameter(Mandatory=$true)]$Username, #global administrator username
    [Parameter(Mandatory=$true)]$Password, #global administrator password
    [Parameter(Mandatory=$true)]$azureAppId #application ID of the azure application you wish to admin-consent to
)

$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($Username, $secpasswd)
$res = login-azurermaccount -Credential $mycreds
$context = Get-AzureRmContext
$tenantId = $context.Tenant.Id
$refreshToken = @($context.TokenCache.ReadItems() | where {$_.tenantId -eq $tenantId -and $_.ExpiresOn -gt (Get-Date)})[0].RefreshToken
$body = "grant_type=refresh_token&refresh_token=$($refreshToken)&resource=74658136-14ec-4630-ad9b-26e160ff0fc6"
$apiToken = Invoke-RestMethod "https://login.windows.net/$tenantId/oauth2/token" -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded'
$header = @{
'Authorization' = 'Bearer ' + $apiToken.access_token
'X-Requested-With'= 'XMLHttpRequest'
'x-ms-client-request-id'= [guid]::NewGuid()
'x-ms-correlation-id' = [guid]::NewGuid()}
$url = "https://main.iam.ad.ext.azure.com/api/RegisteredApplications/$azureAppId/Consent?onBehalfOfAll=true"
Invoke-RestMethod -Uri $url -Headers $header -Method POST -ErrorAction Stop
}

Этот код предоставил разрешение для зарегистрированного приложения Azure AD.Я изменил этот скрипт, чтобы запустить его в приложении C #.

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();

Это дало мне ошибку Parse - Refresh Token искажен или недействителен.Я попробовал следующие вещи, чтобы получить разрешение:

  1. в коде после того, как я получил значение $refreshToken, я попытался разделить строку так, чтобы, если я получаю строку токена дважды, я могу выбрать толькоone.

    $refreshtoken = $refreshtoken.Split(''n')[0];

  2. где-то я обнаружил, что "-", который мы используем в сценарии powershell, например, -AsPlainText, может измениться на endash.Я перепроверил все «-», используемые в скрипте.

  3. В другом разрешении я обнаружил, что когда мы пытаемся получить токен обновления, используя необработанные данные, мы должны использовать ниже URL и параметры.Я получаю этот URL-адрес с этого сайта

    https://login.microsoftonline.com/{tenant}/oauth2/authorize?client_id=<ApplicationId>&response_type=code&&redirect_uri=<Application redirect Url>&response_mode=query

Все, что я пробовал, не работало.Есть ли правильный способ решить эту проблему?Или есть какой-то другой способ получить RefreshToken, который можно использовать для предоставления разрешения?

1 Ответ

0 голосов
/ 07 января 2019

Я думаю, что основная причина кроется в том, что некоторые скрипты 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 # и получите сгенерированные сценарии powershell из c #, иубедитесь, что он совпадает с вашими оригинальными скриптами 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" +

Надеюсь, это поможет.

Получите сгенерированные сценарии ps из кода C #:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...