You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell访问启用SSO/SAML与2FA的网页遇授权问题求助

问题原因分析

你当前的脚本存在核心问题:获取的是Microsoft Graph API的访问令牌,而你的目标网站采用的是SAML-based SSO认证,这两种认证机制不兼容。Graph令牌的受众是https://graph.microsoft.com,目标网站不会识别或接受该令牌,因此返回登录页面是预期结果。

解决方案

要访问SAML认证的网站并获取会话权限,你需要模拟浏览器的完整SAML登录流程,最终获取网站的会话Cookie,而非使用Graph令牌。以下是具体实现思路和示例:

1. 核心思路:模拟SAML登录会话

SAML认证的本质是通过身份提供商(Azure AD)生成断言,提交给目标网站以建立信任会话。你需要:

  • 访问目标网站,触发SAML跳转至Azure AD登录页
  • 完成2FA认证(交互式或自动化方式)
  • 获取目标网站的会话Cookie,用于后续请求

2. PowerShell实现方案(模拟浏览器会话)

方案A:手动交互式获取会话Cookie

通过PowerShell的WebSession保持会话,手动完成2FA认证后复用Cookie:

# 初始化会话对象,用于保持Cookie
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession

# 第一步:访问目标网站,触发SAML跳转
$initialResponse = Invoke-WebRequest -Uri "https://our.website" -WebSession $session -MaximumRedirection 0 -ErrorAction SilentlyContinue

# 第二步:解析跳转的Azure AD登录URL(根据实际响应调整解析逻辑)
$loginUrl = ($initialResponse.Headers.Location | Select-Object -First 1)

# 第三步:打开浏览器手动完成2FA登录,然后导出会话Cookie
# 这里可以用Selenium模块模拟浏览器操作,或者手动登录后从浏览器导出Cookie
# 示例:使用Selenium模拟浏览器登录(需先安装Selenium模块)
Install-Module -Name Selenium -Scope CurrentUser -Force
$driver = Start-SeChrome
$driver.Navigate().GoToUrl($loginUrl)

# 等待你手动完成2FA登录,登录后回到目标网站
Read-Host "请在浏览器中完成登录,按回车继续..."

# 导出浏览器中的会话Cookie到PowerShell的WebSession
$cookies = $driver.Manage().Cookies.AllCookies
foreach ($cookie in $cookies) {
    $sessionCookie = New-Object System.Net.Cookie(
        $cookie.Name,
        $cookie.Value,
        $cookie.Path,
        $cookie.Domain
    )
    $session.Cookies.Add($sessionCookie)
}
$driver.Quit()

# 第四步:使用会话Cookie访问目标网站,下载JNLP文件
$jnlpResponse = Invoke-WebRequest -Uri "https://our.website/path/to/agent.jnlp" -WebSession $session
$jnlpResponse.Content | Out-File -Path "agent.jnlp" -Encoding UTF8

方案B:自动化设备码认证(适合无交互场景)

如果目标网站支持Azure AD的OAuth2设备码流程,可以无需手动打开浏览器完成2FA:

$tenantId = "你的Azure AD租户ID"
$clientId = "注册的Azure AD应用客户端ID" # 需要提前在Azure AD注册应用并授予目标网站的权限

# 获取设备码
$deviceCodeParams = @{
    Uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/devicecode"
    Method = "Post"
    Body = @{
        client_id = $clientId
        scope = "https://our.website/.default" # 替换为目标网站的资源ID
    }
}
$deviceCode = Invoke-RestMethod @deviceCodeParams
Write-Host "请在设备上打开 $($deviceCode.verification_uri),输入代码 $($deviceCode.user_code) 完成认证"

# 轮询获取访问令牌
$tokenParams = @{
    Uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
    Method = "Post"
    Body = @{
        grant_type = "urn:ietf:params:oauth:grant-type:device_code"
        client_id = $clientId
        device_code = $deviceCode.device_code
    }
}
do {
    Start-Sleep -Seconds $deviceCode.interval
    try {
        $tokenResponse = Invoke-RestMethod @tokenParams
        break
    } catch {
        $status = $_.Exception.Response.StatusCode.value__
        if ($status -ne 408 -and $status -ne 400) { throw }
    }
} while ($true)

# 使用访问令牌请求目标网站(仅当目标网站支持OAuth2 Bearer认证时有效,SAML网站可能仍需会话Cookie)
$headers = @{ Authorization = "Bearer $($tokenResponse.access_token)" }
$response = Invoke-WebRequest -Uri "https://our.website" -Headers $headers -WebSession $session

# 若返回登录页面,仍需用方案A的会话Cookie方式

3. 关键注意事项

  • 令牌受众匹配:确保获取的令牌受众是目标网站的资源ID,而非Graph API
  • 会话Cookie复用:SAML认证依赖会话Cookie,而非Bearer令牌,这是访问SAML网站的核心
  • Jenkins Agent替代方案:如果Jenkins本身支持Azure AD SSO,可以直接使用Jenkins的官方认证方式启动Agent,无需手动处理SSO流程

内容的提问来源于stack exchange,提问作者Richard Gledhill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:18:22