5

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.

Community
  • 1
  • 1
Jason Evans
  • 28,906
  • 14
  • 90
  • 154

3 Answers3

8

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.

  • How do you keep them fresh ? – abourget Sep 02 '15 at 01:40
  • How do we keep the cookie fresh? We were not doing any long-term connection with TC, so we never got to the point that the cookie was not valid anymore. But if we had to, we would need to do a check, and in the case of a 401, we would send credentials again. BTW, I'm not working with TeamCity for 2 years now, so I don't know if the solution still applies. – Eduardo Aquiles Jan 11 '16 at 15:23
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.

Jason Evans
  • 28,906
  • 14
  • 90
  • 154
2

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).

mclayton
  • 8,025
  • 2
  • 21
  • 26
  • Thanks for your answer. Unfortunately, I no longer work for the company that used TeamCity in the environment, so I can try your suggestion out. However, I do appreciate your input :) – Jason Evans Jan 03 '14 at 15:29