Log onto TeamCity server using REST API without pa

2020-07-17 06:34发布

问题:

As a follow up to a previous question I asked: How to pass username and password in TeamCity REST API, I'd like to check on something.

Can someone tell me if it's possible to access the TeamCity REST API in a more secure way, rather then passing the username and password in the url?

It just seems crazy to me that passing credentials in the url is the only way, since it's so easy for a sniffer to get their hands on the url and use the credentials themselves.

回答1:

We faced the same problem and I spent some time to see how could we solve this problem and found a way:

You do a get in the initial screen (/ntlmLogin.html) - you'll be able to identify the user using NTLM.
Then you save the cookie that TeamCity provides to you.
Now you use the cookie to reach the API.

See https://github.com/eduaquiles/TeamCityNtlmApiWrapper with a very simple example on how to do this.



回答2:

I've done some more digging around with this and it does not look too promising.

I found the following thread on the TeamCity community forums:

Rest API Authentication Integrated

http://devnet.jetbrains.net/message/5461520#5461520

Another user had asked a similar question to mine and the response was that basic HTTP authentication is currently the only option. Although you can use NTLM authentication, that is tailored towards the front end web UI, not the REST API.

I have asked on the forum whether using NTLM via the REST API is possible. I've not had a reply, but I can imagine that it's not possible, which would be expected in this case.



回答3:

As per Eduardo Aquiles, if you configure your TeamCity server to support HTTP NTLM authentication (TeamCity 8.x NTLM HTTP Authentication), you can get a session cookie (TCSESSIONID) from the /ntlmLogin.html url and use that to authenticate against the REST API.

I've just had to do something similar to get the pinned state of builds. Here's the PowerShell I used:

function Get-TeamCityNtlmAuthCookie()
{
    param( [string] $serverUrl )
    $url = "$serverUrl/ntlmLogin.html";
    $cookies = new-object System.Net.CookieContainer;
    $request = [System.Net.WebRequest]::Create($url);
    $request.CookieContainer = $cookies;
    $request.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials;
    $request.PreAuthenticate = $true;
    $response = $request.GetResponse();
    return $cookies;
}

function Get-TeamCityBuildPinnedState()
{
    param( [string] $serverUrl, [string] $buildTypeId)
    # get a session cookie to use with the rest api
    $cookies = Get-TeamCityNtlmAuthCookie $serverUrl;
    # query the rest api using the session cookie for authentication
    $url = "$serverUrl/httpAuth/app/rest/builds/id:$buildTypeId/pin/";
    $request = [System.Net.WebRequest]::Create($url);
    $request.CookieContainer = $cookies;
    $response = $request.GetResponse();
    $stream = $response.GetResponseStream();
    $reader = new-object System.IO.StreamReader($stream);
    $text = $reader.ReadToEnd();
    $reader.Close();
    return [bool]::Parse($text);
}

$myServerUrl = "http://myTeamCityServer";
$myBuildId = "6";

$pinned = Get-TeamCityBuildPinnedState $myServerUrl $myBuildId;
write-host $pinned;

Note: I'm not sure if this is officially supported by JetBrains, so you might find it breaks in a future version of TeamCity, but it currently works against version 8.0.2 (build 27482).