如何使用PowerShell打开和接收Azure Active Directory OAuth授权代码授权流程的授权对话框中的响应

时间:2018-05-24 08:16:03

标签: powershell azure oauth-2.0 azure-active-directory

我正在尝试编写一个PowerShell脚本,允许用户授权Azure Active Directory应用程序代表他们行事。

遵循授权代码授权流程documentation from Microsoft。我使用以下行调用Authorization端点:

Invoke-WebRequest -Method GET -Uri "https://login.microsoftonline.com/$tenantId/oauth2/authorize?client_id=$applicationId&response_type=code&redirect_uri=$redirectUri&response_mode=query&resource=$resource&state=09876"

它同时在PowerShell中返回响应并同时在我的默认浏览器上打开一个网页。

以下是回复的内容:

StatusCode        : 200
StatusDescription : OK
Content           :

                    <!DOCTYPE html>
                    <html dir="ltr" class="" lang="en">
                    <head>
                        <title>Sign in to your account</title>
                        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
                        <meta http-eq...
RawContent        : HTTP/1.1 200 OK
                    Pragma: no-cache
                    Strict-Transport-Security: max-age=31536000; includeSubDomains
                    X-Content-Type-Options: nosniff
                    X-Frame-Options: DENY
                    x-ms-request-id: ed3ee9de-ccc4-47ea-ac52-087b...
Forms             : {}
Headers           : {[Pragma, no-cache], [Strict-Transport-Security, max-age=31536000; includeSubDomains],
                    [X-Content-Type-Options, nosniff], [X-Frame-Options, DENY]...}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 22592

浏览器中显示的网页被重定向到https://login.microsoftonline.com/cookiesdisabled,并显示以下消息:

  

我们无法签到你   您的浏览器目前已设置为阻止Cookie。您需要允许cookie才能使用此服务。   Cookie是存储在您计算机上的小文本文件,告诉我们您何时登录。要了解如何允许Cookie,请查看网络浏览器中的在线帮助。

总而言之,它不起作用!

请注意,我的浏览器启用了Cookie,如果我从网络浏览器调用网页请求,它就会正常工作。

我做错了什么?如何使用PowerShell向用户提示对话框并在PowerShell中接收授权代码响应?

谢谢。

1 个答案:

答案 0 :(得分:2)

你是对的。这是因为Poweshell无法捕获回复URL返回的授权代码。

<强>解决方案:

你可以写一个登录浏览器mudule作为&#34;假的&#34;与回复URL一起返回的授权代码的端点。

尝试使用this Example

<强> LoginBrowser

Add-Type -AssemblyName System.Web
$outputAuth = ".\Code.txt"
$outputError = ".\Error.txt"

function LoginBrowser
{
    param
    (
        [Parameter(HelpMessage='Authorization URL')]
        [ValidateNotNull()]
        [string]$authorizationUrl,

        [Parameter(HelpMessage='Redirect URI')]
        [ValidateNotNull()]
        [uri]$redirectUri
    )

    # Create an Internet Explorer Window for the Login Experience
    $ie = New-Object -ComObject InternetExplorer.Application
    $ie.Width = 600
    $ie.Height = 500
    $ie.AddressBar = $false
    $ie.ToolBar = $false
    $ie.StatusBar = $false
    $ie.visible = $true
    $ie.navigate($authorzationUrl)

    while ($ie.Busy) {} 

    :loop while($true)
    {   
        # Grab URL in IE Window
        $urls = (New-Object -ComObject Shell.Application).Windows() | Where-Object {($_.LocationUrl -match "(^https?://.+)|(^ftp://)") -and ($_.HWND -eq $ie.HWND)} | Where-Object {$_.LocationUrl}

        foreach ($a in $urls)
        {
            # If URL is in the form we expect, with the Reply URL as the domain, and the code in the URL, grab the code
            if (($a.LocationUrl).StartsWith($redirectUri.ToString()+"?code="))
            {
                $code = ($a.LocationUrl)
                ($code = $code -replace (".*code=") -replace ("&.*")) | Out-File $outputAuth
                break loop
            }
            # If we catch an error, output the error information
            elseif (($a.LocationUrl).StartsWith($redirectUri.ToString()+"?error="))
            {
                $error = [System.Web.HttpUtility]::UrlDecode(($a.LocationUrl) -replace (".*error="))
                $error | Out-File $outputError
                break loop
            }
        }
    }

    # Return the Auth Code
    return $code
}

使用AUTHCODE的REST

# Load ADAL
Add-Type -Path "..\ADAL\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"

# Load our Login Browser Function
Import-Module ./LoginBrowser.psm1

# Output Token and Response from AAD Graph API
$accessToken = ".\Token.txt"
$output = ".\Output.json"

# Application and Tenant Configuration
$clientId = "<AppIDGUID>"
$tenantId = "<TenantID>"
$resourceId = "https://graph.windows.net"
$redirectUri = New-Object system.uri("<ReplyURL>")
$login = "https://login.microsoftonline.com"

# Create Client Credential Using App Key
$secret = "<AppKey>"

# Create Client Credential Using Certificate
#$certFile = "<PFXFilePath>"
#$certFilePassword = "<CertPassword>"
#$secret = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate -ArgumentList $certFile,$certFilePassword

# Note you can adjust the querystring paramters here to change things like prompting for consent
$authorzationUrl = ("{0}/{1}/oauth2/authorize?response_type=code&client_id={2}&redirect_uri={3}&resource={4}&prompt=consent" -f $login,$tenantId,$clientId,$redirectUri,$resourceId)
# Fake a proper endpoint for the Redirect URI
$code = LoginBrowser $authorzationUrl $redirectUri

# Get an Access Token with ADAL
$clientCredential = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential($clientId,$secret)
$authContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext("{0}/{1}" -f $login,$tenantId)
$authenticationResult = $authContext.AcquireToken($resourceId, $clientcredential)
($token = $authenticationResult.AccessToken) | Out-File $accessToken


# Call the AAD Graph API 
$headers = @{ 
    "Authorization" = ("Bearer {0}" -f $token);
    "Content-Type" = "application/json";
}

# Output response as JSON file
Invoke-RestMethod -Method Get -Uri ("{0}/{1}/users?api-version=1.6" -f $resourceId,$tenantId)  -Headers $headers -OutFile $output