POST 构建到 TeamCity 队列

POST build to TeamCity queue

我正在尝试使用 TeamCity REST API 将构建添加到队列中,但 运行 在授权方面遇到了一些困难。

我定义了 url 到我们的 teamcity 服务器,并通过管理页面生成了授权令牌

TEAMCITY_URL = 'http://teamcity.somedomain.com'
BEARER_TOKEN = 'SOMELONGTOKEN'

有了这个 URL 和令牌,我可以成功地发出 GET 请求

import json
import requests

session = requests.Session()
session.headers.update({
    'Accept': 'application/json',
    'Authorization': f'Bearer {BEARER_TOKEN}',
})

response = session.get(f'{TEAMCITY_URL}/app/rest/projects/example/buildTypes')
assert(response.status_code == requests.codes.ok)  # this succeeds, can parse response fine later

但是如果我尝试 POST 构建队列,我会得到一个 403

payload = {
    'branchName': 'master',
    'buildType': {
        'id': buildID  # assume this was already defined
    }
}

response = session.post(f'{TEAMCITY_URL}/app/rest/buildQueue', json=payload)
assert(response.status_code == requests.codes.ok)  # fails with 403

后者response.text

'403 Forbidden: Responding with 403 status code due to failed CSRF check: authenticated POST request is made, but neither tc-csrf-token parameter nor X-TC-CSRF-Token header are provided.. For a temporary workaround, you can set internal property teamcity.csrf.paranoid=false and provide valid Origin={teamcity_url} header with your request\n'

如何正确使用此不记名令牌来执行 POST 请求?

解决这个问题的方法是我需要先对 CSRF 令牌发出 GET 请求。然后我可以使用此令牌用 'X-TC-CSRF-Token' 更新 session headers,如下所示

response = session.get(f'{TEAMCITY_URL}/authenticationTest.html?csrf')
assert(response.status_code == requests.codes.ok)
csrf_token = response.text
session.headers.update({
    'X-TC-CSRF-Token': csrf_token
})

那么后面的POST就会成功。 official docs.

中有更多详细信息