【问题标题】:Invoke-RestMethod on an app requiring Azure authentication需要 Azure 身份验证的应用程序上的 Invoke-RestMethod
【发布时间】:2019-03-05 07:37:57
【问题描述】:

如何使用 Powershell 在 Azure 身份验证后调用 API? 更具体地说,我确实希望这条线起作用: Invoke-RestMethod -Method Get -Uri 'https://contoso.com/api/Hello

我的 API 是本地的(但在 Web 上可见)并且配置了 Azure AD 身份验证并且是强制性的。

我希望以编程方式通过 Powershell 进行身份验证,这样我就可以调用 API 而无需任何额外的交互。

目前,无论我做什么,我在执行Invoke-RestMethod 时都会遇到 401 错误。

关于 API

我正在使用通过 Visual Studio 创建的示例 asp.net core c# 应用程序(使用工作或学校身份验证方法)。 这个过程在 Azure 中创建了应用程序注册,我确实在 Azure 中手动创建了一个客户端密码。

我的尝试

现在,使用 Powershell,我填写了以下内容

$Params = @{
    'client_id' = '' 
    'Redirect_URI' = ''
    'TenantID' = '' 
    'response_type'='code'

}
$ClientSecret = ''

从那里,我确实得到了一个授权码:

$Query = "?"; $Params.Keys | % {$Query+= "$($_)=$($Params.Item($_))&"} ; $Query = $Query.TrimEnd('&')


$IE= new-object -ComObject "InternetExplorer.Application"
$IE.Visible = $true
$IE.navigate2("https://login.microsoftonline.com/$($params.TenantID)/oauth2/authorize$Query")
Write-Host 'Press enter when Code is displayed in URL'

pause 
$Code = [System.Web.HttpUtility]::ParseQueryString(([uri]$ie.LocationURL).Query)['code']
$ie.quit()

最后,我使用以下方法获取访问令牌:

$TokenResult = Invoke-RestMethod -Method Post -ContentType 'application/x-www-form-urlencoded' -Uri "https://login.microsoftonline.com/$($Params.TenantID)/oauth2/v2.0/token" -Body @{
    client_id     = $Params.client_id
    scope         = 'User.Read offline_access'
    code          = $Code
    redirect_uri  = $Params.Redirect_URI
    grant_type    = 'authorization_code'
    client_secret = $ClientSecret
} 

但是,如果我现在尝试使用以下方式调用我的 API:

Invoke-RestMethod 'https://SomeDomain.com/api/values' -Headers @{Authorization = "Bearer $($TokenResult.access_token)"}

结果

我确实得到了未经授权的 401

我的观察

我相信我成功地使用了以下方法与 Graph API 和其他 Azure API 进行交互。但是,这在调用我自己的 Azure 身份验证背后的 API 时不起作用。

我应该如何进行适当的调用,以允许我使用 Azure 身份验证针对我的私有 API 进行身份验证?

【问题讨论】:

    标签: azure powershell azure-active-directory


    【解决方案1】:

    我想您尚未在 AAD 中配置您的 API。要通过您的 AD App 访问 api,您还需要在门户中为您的 api 创建一个 AD App,请参阅:Register an app with the Azure Active Directory v2.0 endpoint. 并将其配置为公开 API,请参阅:Configure an application to expose web APIs (Preview)Configure a client application to access web APIs (Preview)。然后就可以调用 Graph API、Office 365 API 等 API。

    您可以通过公开权限/范围和角色来开发 Web API 并使其可供客户端应用程序使用。正确配置的 Web API 与其他 Microsoft Web API 一样可用,包括 Graph API 和 Office 365 API。

    【讨论】:

    • 看起来我正在尝试做的事情(调用 contoso.com/api/Hello)可能是“配置应用程序以公开 Web API”链接的一部分。我会朝那个方向进一步挖掘。谢谢。
    • @SagePourpre 是的,如果您还有其他问题,请告诉我。或者如果我的解决方案解决了您的问题,请接受它作为答案,谢谢。
    • 实际上,我想要实现的只是:Invoke-RestMethod -Method Get -Uri 'https://contoso.com/api/Hello' 应该返回 World。相反,我得到了 401。我不清楚如何进行这项工作并且仍在寻找。我确实得到了一个访问令牌。并使用授权承载标头,我可以获得图形 api 来返回我的信息,但我想调用我的 api 而不是 Azure 的。我仍在努力解决这个问题。
    【解决方案2】:

    根据您的脚本,您需要将您的 Header 指定为Headers @{Authorization = "Bearer "+ $TokenResult.access_token}。我使用了一个示例。

    $Params = @{
        'client_id' = '' 
        'redirect_URI' = ''
        'response_type'='code'
        'scope' = 'https://graph.microsoft.com/.default offline_access'
    }
    $ClientSecret ='.C$S|NAYQ:q)ES2w(A)*]Xp5T-?Fx+[aKE+YtmcaX!u1!{>T*wVJ70h:Q2s'
    $TeantID = 'e4c9ab4e-bd27-40d5-8459-230ba2a757fb'
    $Query = "?"; $Params.Keys | % {$Query+= "$($_)=$($Params.Item($_))&"} ; $Query = $Query.TrimEnd('&')
    
    
    $IE= new-object -ComObject "InternetExplorer.Application"
    $IE.Visible = $true
    $IE.navigate2("https://login.microsoftonline.com/$($TeantID)/oauth2/authorize$Query")
    Write-Host 'Press enter when Code is displayed in URL'
    pause 
    Add-Type -AssemblyName System.Web
    $Code = [System.Web.HttpUtility]::ParseQueryString(([uri]$ie.LocationURL).Query)['code']
    $ie.quit()
    
    $TokenResult = Invoke-RestMethod -Method Post -ContentType 'application/x-www-form-urlencoded' -Uri "https://login.microsoftonline.com/$($TeantID)/oauth2/v2.0/token" -Body @{
        client_id     = $Params.client_id
        scope         = 'User.Read offline_access'
        code          = $Code
        redirect_uri  = $Params.Redirect_URI
        grant_type    = 'authorization_code'
        client_secret = $ClientSecret
    }
    
     Invoke-RestMethod -Method Get -Uri 'https://graph.microsoft.com/v1.0/me' -Headers @{Authorization = "Bearer "+ $TokenResult.access_token}
    

    更多详情请参考https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow

    【讨论】:

    猜你喜欢
    • 2019-11-20
    • 2017-11-23
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    • 2011-10-18
    相关资源
    最近更新 更多