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

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

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

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

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,并显示以下消息:

We can't sign you in Your browser is currently set to block cookies. You need to allow cookies to use this service. Cookies are small text files stored on your computer that tell us when you're signed in. To learn how to allow cookies, check the online help in your web browser.

总而言之,它不起作用!

请注意,我的浏览器中启用了 cookie,如果我从 Web 浏览器调用 Web 请求,它将正常工作。

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

谢谢。

最佳答案

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

解决方案:

您可以编写一个登录浏览器模块来充当随回复 URL 返回的授权代码的“假”端点。

尝试使用this Example :

登录浏览器

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
}

使用授权码进行休息

# 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

关于powershell - 如何使用 PowerShell 打开 Azure Active Directory OAuth 授权代码授予流程的授权对话框并接收响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50504289/

相关文章:

grails - scribe oauth linkedin 创建 token

spring-boot - 为什么在为访问 token 交换授权代码时收到无效 token 响应? ( Spring 启动、oauth2、天蓝色)

regex - 使用内容定界符作为文件名在PowerShell中拆分文本

Powershell实现Switch语句

azure - 无法解析远程名称 : 'dev.azure.com' when setting up self-hosted devops agent in Docker

sql-server - 如何修复从 Visual Studio 到 Azure VM 中部署到 SQL Server 2014 的缓慢问题

node.js - “需要登录”错误。使用 Google API 获取 oauth2 token 后如何登录

使用PowerShell脚本下载zip文件并解压缩

winforms - 如何通过 VBS 将变量从一个 PS 脚本传递到另一个 PS 脚本?

azure - terraform azurerm 功能应用程序设置 host.json 文档丢失