2017-09-28 105 views
0

我正在編寫一個MVC5 Web應用程序,以允許我在Visual Studio Team Services(VSTS)中查詢我們的工作項目。如何使用授權例程提供的VSTS OAuth2承載令牌?

已經按照教程this onethis one我已成功創建應用程序,以便它將檢索使用我爲開發目的創建的個人訪問令牌(PAT)所需的工作項目。我還密切關注示例here,成功創建了整個OAuth2過程,以便用戶被帶到VSTS,被要求授權我的應用程序,然後返回到我的回調頁面。回撥URL正確包含用戶的訪問令牌,刷新令牌等。到現在爲止還挺好。

我將用戶的刷新令牌存儲在他們的用戶記錄中的數據庫中,以及有效日期和時間(以便我知道如果他們在訪問令牌已過期後嘗試訪問應用程序時刷新令牌)。

我的問題是,我不知道如何使用Access Token來代替用戶查詢VSTS的C#代碼中的自己的PAT。我使用的代碼如下(它實際上與我在上面鏈接的GitHub上的示例中的代碼相同),並且它工作正常,但正如您可以看到它使用PAT。我該如何使用用戶的訪問令牌,目前我只是將其作爲string作爲API返回(可能是錯誤的?)。

public class GetFeatures 
{ 
    readonly string _uri; 
    readonly string _personalAccessToken; 
    readonly string _project; 

    public GetFeatures() 
    { 
     _uri = "https://myaccount.visualstudio.com"; 
     _personalAccessToken = "abc123xyz456"; //Obviously I've redacted my actual PAT 
     _project = "My Project"; 
    } 

    public List<VSTSFeatureModel> AllFeatures() 
    { 
     Uri uri = new Uri(_uri); 
     string personalAccessToken = _personalAccessToken; 
     string project = _project; 

     VssBasicCredential credentials = new VssBasicCredential("", _personalAccessToken); 

     //create a wiql object and build our query 
     Wiql wiql = new Wiql() 
     { 
      Query = "Select [State], [Title] " + 
        "From WorkItems " + 
        "Where [Work Item Type] = 'Feature' " + 
        "And [System.TeamProject] = '" + project + "' " + 
        "And [System.State] <> 'Removed' " + 
        "Order By [State] Asc, [Changed Date] Desc" 
     }; 

     //create instance of work item tracking http client 
     using (WorkItemTrackingHttpClient workItemTrackingHttpClient = new WorkItemTrackingHttpClient(uri, credentials)) 
     { 
      //execute the query to get the list of work items in the results 
      WorkItemQueryResult workItemQueryResult = workItemTrackingHttpClient.QueryByWiqlAsync(wiql).Result; 

      //some error handling     
      if (workItemQueryResult.WorkItems.Count() != 0) 
      { 
       //...do stuff     
      } 

      return null; 
     } 
    } 
} 

回答

0

經過大量的猜測,由於VSTS .NET客戶端庫的記錄很差,我發現VssOAuthCredential似乎不推薦使用。我能夠通過更換

VssBasicCredential credentials = new VssBasicCredential("", _personalAccessToken) 

讓我的工作上面的代碼示例與

VssOAuthAccessTokenCredential credentials = new VssOAuthAccessTokenCredential(AccessToken); 

其中的accessToken是包含用戶的OAuth訪問令牌的string

0

您需要使用VssOAuthCredential而不是VssBasicCredential

+0

我想知道這是否是這樣的,但是看着班級要求的參數,我不知道應該傳遞什麼樣的價值觀,而且看起來太複雜了。我有用戶的訪問令牌,當然,我所需要做的就是將其包含在我對API的請求中(如「使用訪問令牌」一節中所暗示的:https://docs.microsoft.com/en- gb/vsts/integrate/get-started/authentication/oauth,儘管沒有說明如何在.NET客戶端庫中這樣做)。 –

0

該框架似乎相當無用的,哈哈......

我目前工作的一個項目備份VSTS帳戶和我做這一切通過HTTPRequests的到REST API。

public List<int> GetItemIDs() 
    { 
     HttpClient client = auth.AuthenticateHTTP(new HttpClient()); 
     string content = [email protected]"{{""query"": ""Select[System.Id] From WorkItems order by[System.CreatedDate] desc"" }}"; 
     StringContent stringContent = new StringContent(content, Encoding.UTF8, "application/json"); 
     string endpoint = "DefaultCollection/_apis/wit/wiql?api-version=1.0"; 
     Uri requesturl = UriCombine(baseurl, endpoint); 
     HttpResponseMessage response = client.PostAsync(requesturl, stringContent).Result; 
     string result = response.Content.ReadAsStringAsync().Result; 
     var json = Newtonsoft.Json.JsonConvert.DeserializeObject<QueryResponse>(result); 
     return json.workItems.Select(x => x.id).ToList(); 
    } 

public List<string> ListToString200(List<int> ids) //Writes all IDs into comma seperated strings of up to 200 IDs and puts them into a List. 
     { 
      List<string> idStrings = new List<string>(); 

      if (ids.Count > 200) 
      { 
       while (ids.Count > 200) 
       { 
        List<int> t = new List<int>(); 
        var IDs = ids.Take(200); 
        ids.Remove(200); 
        foreach (var item in IDs) 
        { 
         t.Add(item); 
        } 

        var ID = t.ConvertAll(element => element.ToString()).Aggregate((a, b) => $"{a},{b}"); 
        idStrings.Add(ID); 
       } 
      } 
      else if (ids.Count > 0) 
      { 
       var ID = ids.ConvertAll(element => element.ToString()).Aggregate((a, b) => $"{a}, {b}"); 
       idStrings.Add(ID); 
      } 

      return idStrings; 
     } 


private List<WorkItem> GetAllWorkItems() 
     { 
      List<int> ids = GetItemIDs(); 
      List<WorkItemsContainer> Responses = new List<WorkItemsContainer>(); 
      List<WorkItem> ResultList = new List<WorkItem>(); 

      List<string> idStrings = ListToString200(ids); 

      using (HttpClient client = new HttpClient()) 
      { 
       auth.AuthenticateHTTP(client); 

       foreach (var item in idStrings) 
       { 
        WorkItemsContainer WorkItem = new WorkItemsContainer(); 

        string featurePath = $"DefaultCollection/_apis/wit/workitems?ids={item}&$expand=all&api-version=1.0"; 
        Uri requestUri = Authenticator.UriCombine(baseurl, featurePath); 
        HttpResponseMessage response = client.GetAsync(requestUri).Result; 
        string result = response.Content.ReadAsStringAsync().Result; 
        result = result.Replace("System.", "System"); 

        WorkItem = JsonConvert.DeserializeObject<WorkItemsContainer>(result); 
        Responses.Add(WorkItem); 
       } 
      } 

      foreach (var item in Responses) 
      { 
       foreach (var x in item.value.ToList<WorkItem>()) 
       { 
        WorkItemsToJsonFile(x); 
        ResultList.Add(x); 
       } 
      } 
      return ResultList; 
     } 

與固定登錄容易得多,不需要的oauth2雖然,這樣做的OAuth2手動是不是更難,只是把將令牌承載認證頭......

+0

我希望自己剛開始使用REST API,但當我發佈我的問題時,我就投入了.NET客戶端庫!我最終得到了它 - 看到我發佈的答案。另外,我熱衷於使用OAuth,因爲我將有多個用戶訪問我的應用程序,我希望他們能夠以自己的身份讀取/寫入API。但是,如果您可以告訴我如何在Ajax調用中成功傳遞OAuth訪問令牌(可以使用PAT執行,無法找出訪問令牌),那麼您將成爲我的英雄! –

+0

從未聽說過PAT tbh :( 在C#中,使用HttpClient它是'httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(「承載者」,「你的Oauth標記」);'' – Vaethin

相關問題