Search code examples
restpowershelltfstfs-2015

Problem to connect to TFS with user/password


When I try to connect to tfs the function Get-Data failed with 401 error although the function Get-DataWithCred succeed with the same argument.

And don't understand the difference with this two ?

function Get-Data([string]$username, [string]$password, [string]$url) 
{
  # Step 1. Create a username:password pair
  $credPair = "$($username):$($password)"

  # Step 2. Encode the pair to Base64 string
  $encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair))

  # Step 3. Form the header and add the Authorization attribute to it
  $headers = @{ Authorization = "Basic $encodedCredentials" }

  # Step 4. Make the GET request
  $responseData =  Invoke-WebRequest -Uri $url -Method Get -Headers $headers
  return $responseData
}


function Get-DataWithCred([string]$username, [string]$password, [string]$url) 
{
  $p = ConvertTo-SecureString -String $password -AsPlainText -Force

  $Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $p

  $responseData =  Invoke-WebRequest -Uri $url -Method Get  -Credential $Cred
  return $responseData
}

The purpose is too connect through tfs with python script who failed the same way that the function Get-Data when I use the requests library.

>>> r = requests.get('https://tfs-url.com', auth=('user', 'pass'))
>>> r.status_code
401

Solution

  • You need to use a microsoft way to pass your credential : the ntlm protocol.

    This protocol are not supported by default by requests but a library requests_ntlm extend requests by adding support to ntlm.

    A simple example:

    import os
    import requests
    from requests_ntlm import HttpNtlmAuth
    
    
    def main():
        user = "user"
        password = "password"
    
        session = requests.Session()
        session.auth = HttpNtlmAuth(user, password)
    
        url = "https://tfs-url.com"
    
        response = session.get(url)
    
        print(response)
    
    
    if __name__ == "__main__":
        main()