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

如何在PowerShell中通过REST使用OAuth登录禁用明文基础认证的JIRA?

解决JIRA Server OAuth认证访问问题

首先纠正一个小问题:你调用的API路径有误,正确的JIRA Agile API路径应该是/rest/agile/1.0/issue/test-1,而非/jira-software/REST/agile/1.0/issue/test-1,路径大小写和前缀都需要调整。

针对JIRA Server不再支持Basic Auth的情况,我们可以通过OAuth 1.0a完成认证,以下是完整的配置和调用步骤:

一、JIRA Server端配置OAuth应用链接

  1. 登录JIRA管理员后台,进入应用管理 > 应用链接
  2. 点击创建应用链接,输入任意一个占位URL(比如http://localhost:8081,仅用于初始化配置),点击继续
  3. 在应用链接配置页,填写应用名称(例如PowerShell OAuth Client),勾选创建传入链接,点击下一步
  4. 填写OAuth核心配置:
    • 消费者密钥:自定义唯一标识(例如powershell-jira-oauth)
    • 消费者名称:与应用名称一致即可
    • 公钥:后续生成RSA公钥后,将公钥内容粘贴此处
    • 点击保存

二、生成RSA密钥对(用于OAuth签名)

在PowerShell中执行以下命令生成密钥对,保存到本地文件:

# 创建RSA加密服务实例
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider(2048)
# 导出私钥(带私钥的XML格式)
$rsa.ToXmlString($true) | Out-File "C:\temp\jira-oauth-private.xml"
# 导出公钥(仅公钥的XML格式)
$rsa.ToXmlString($false) | Out-File "C:\temp\jira-oauth-public.xml"

打开公钥文件,去掉<RSAKeyValue>等XML标签,仅保留中间的Base64字符串,粘贴到JIRA的公钥配置字段中。

三、获取OAuth访问令牌

1. 获取请求令牌

# 加载本地私钥
$privateKeyXml = Get-Content "C:\temp\jira-oauth-private.xml" -Raw
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider
$rsa.FromXmlString($privateKeyXml)

# 构建OAuth基础参数
$oauthParams = @{
    oauth_consumer_key = "powershell-jira-oauth"  # 替换为你设置的消费者密钥
    oauth_signature_method = "RSA-SHA1"
    oauth_timestamp = [int][double]::Parse((Get-Date -UFormat %s))
    oauth_nonce = [System.Guid]::NewGuid().ToString().Replace("-", "")
    oauth_version = "1.0"
    oauth_callback = "oob"  # 桌面客户端固定用oob
}

# 生成签名基字符串
$requestTokenUrl = "http://jiraserver:8080/plugins/servlet/oauth/request-token"
$sortedParams = $oauthParams.GetEnumerator() | Sort-Object Name | ForEach-Object { "$($_.Key)=$([Uri]::EscapeDataString($_.Value))" }
$baseString = "GET&$([Uri]::EscapeDataString($requestTokenUrl))&$([Uri]::EscapeDataString($sortedParams -join "&"))"

# 生成RSA签名
$signatureBytes = [System.Text.Encoding]::ASCII.GetBytes($baseString)
$signature = [Convert]::ToBase64String($rsa.SignData($signatureBytes, [System.Security.Cryptography.HashAlgorithmName]::SHA1, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1))
$oauthParams["oauth_signature"] = [Uri]::EscapeDataString($signature)

# 构建Authorization请求头
$authHeaderParts = $oauthParams.GetEnumerator() | ForEach-Object { "$($_.Key)=`"$($_.Value)`"" }
$authHeader = "OAuth $($authHeaderParts -join ", ")"

# 发送请求获取请求令牌
$response = Invoke-RestMethod -Uri $requestTokenUrl -Headers @{Authorization = $authHeader} -Method Get -AllowUnencryptedAuthentication
$requestTokenData = [System.Web.HttpUtility]::ParseQueryString($response)
$oauthToken = $requestTokenData["oauth_token"]
$oauthTokenSecret = $requestTokenData["oauth_token_secret"]

2. 手动授权令牌

将上述代码得到的$oauthToken值复制,在浏览器中打开JIRA授权页面:

http://jiraserver:8080/plugins/servlet/oauth/authorize?oauth_token=$oauthToken

登录JIRA账号后点击授权,记录页面返回的验证码(verifier code)。

3. 交换访问令牌

# 构建带验证码的OAuth参数
$accessTokenParams = @{
    oauth_consumer_key = "powershell-jira-oauth"
    oauth_signature_method = "RSA-SHA1"
    oauth_timestamp = [int][double]::Parse((Get-Date -UFormat %s))
    oauth_nonce = [System.Guid]::NewGuid().ToString().Replace("-", "")
    oauth_version = "1.0"
    oauth_token = $oauthToken
    oauth_verifier = "替换为你获取的验证码"
}

# 生成签名基字符串
$accessTokenUrl = "http://jiraserver:8080/plugins/servlet/oauth/access-token"
$sortedAccessParams = $accessTokenParams.GetEnumerator() | Sort-Object Name | ForEach-Object { "$($_.Key)=$([Uri]::EscapeDataString($_.Value))" }
$accessBaseString = "GET&$([Uri]::EscapeDataString($accessTokenUrl))&$([Uri]::EscapeDataString($sortedAccessParams -join "&"))"

# 生成签名
$accessSignatureBytes = [System.Text.Encoding]::ASCII.GetBytes($accessBaseString)
$accessSignature = [Convert]::ToBase64String($rsa.SignData($accessSignatureBytes, [System.Security.Cryptography.HashAlgorithmName]::SHA1, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1))
$accessTokenParams["oauth_signature"] = [Uri]::EscapeDataString($accessSignature)

# 构建Authorization头
$accessAuthHeaderParts = $accessTokenParams.GetEnumerator() | ForEach-Object { "$($_.Key)=`"$($_.Value)`"" }
$accessAuthHeader = "OAuth $($accessAuthHeaderParts -join ", ")"

# 交换获取永久访问令牌
$accessResponse = Invoke-RestMethod -Uri $accessTokenUrl -Headers @{Authorization = $accessAuthHeader} -Method Get -AllowUnencryptedAuthentication
$accessTokenData = [System.Web.HttpUtility]::ParseQueryString($accessResponse)
$finalOAuthToken = $accessTokenData["oauth_token"]
$finalOAuthTokenSecret = $accessTokenData["oauth_token_secret"]

四、使用OAuth令牌调用JIRA API

# 构建API请求的OAuth参数
$apiParams = @{
    oauth_consumer_key = "powershell-jira-oauth"
    oauth_signature_method = "RSA-SHA1"
    oauth_timestamp = [int][double]::Parse((Get-Date -UFormat %s))
    oauth_nonce = [System.Guid]::NewGuid().ToString().Replace("-", "")
    oauth_version = "1.0"
    oauth_token = $finalOAuthToken
}

# 目标API地址
$apiUrl = "http://jiraserver:8080/rest/agile/1.0/issue/test-1"

# 生成签名基字符串
$sortedApiParams = $apiParams.GetEnumerator() | Sort-Object Name | ForEach-Object { "$($_.Key)=$([Uri]::EscapeDataString($_.Value))" }
$apiBaseString = "GET&$([Uri]::EscapeDataString($apiUrl))&$([Uri]::EscapeDataString($sortedApiParams -join "&"))"

# 生成签名
$apiSignatureBytes = [System.Text.Encoding]::ASCII.GetBytes($apiBaseString)
$apiSignature = [Convert]::ToBase64String($rsa.SignData($apiSignatureBytes, [System.Security.Cryptography.HashAlgorithmName]::SHA1, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1))
$apiParams["oauth_signature"] = [Uri]::EscapeDataString($apiSignature)

# 构建Authorization头
$apiAuthHeaderParts = $apiParams.GetEnumerator() | ForEach-Object { "$($_.Key)=`"$($_.Value)`"" }
$apiAuthHeader = "OAuth $($apiAuthHeaderParts -join ", ")"

# 发送API请求
$issueData = Invoke-RestMethod -Uri $apiUrl -Headers @{Authorization = $apiAuthHeader} -ContentType "application/json" -AllowUnencryptedAuthentication
$issueData

注意事项

  • 保存好私钥文件和最终的访问令牌/密钥,后续调用API可直接复用,无需重复授权流程
  • 确认JIRA Server已启用OAuth 1.0a:在管理员后台进入系统 > 安全 > OAuth检查配置
  • 若JIRA Server版本较新,需确保用户账号有API访问权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 23:10:30