VSTS Web Api дает 403 несанкционированный ответ

Я создал собственное приложение в Azure с помощью регистрации приложения и добавил необходимые разрешения для агента VSTS.

Теперь я могу войти в систему, используя аутентификацию oauth с помощью «ADAL» и получить токен, но при попытке доступа к запросу веб-API он дает ответ Http 403.

Вот пример кода ниже

    using (HttpClient client = new HttpClient())
        {
            client.BaseAddress = new Uri(vstsCollectionUrl);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));               
            client.DefaultRequestHeaders.Add("X-TFS-FedAuthRedirect", "Suppress");
            client.DefaultRequestHeaders.Authorization = authHeader;

            HttpResponseMessage res = client.GetAsync(webapiURL).Result;
        }

Пожалуйста, дайте мне знать, что мне не хватает

заранее спасибо


person Shyam    schedule 31.07.2018    source источник
comment
Каково значение authHeader?   -  person Daniel Mann    schedule 31.07.2018
comment
authHeader является экземпляром AuthenticationHeaderValue. authHeader состоит из токена oauth и передает его в качестве параметра авторизации HttpClient.   -  person Shyam    schedule 01.08.2018
comment
@Shyam Кажется, это проблема аутентификации. Просто проверьте значение authHeader, см. приведенные ниже примеры для устранения неполадок: Пример 1- примеры аутентификации здесь ; Пример 2REST API   -  person Andy Li-MSFT    schedule 01.08.2018
comment
@ AndyLi-MSFT Я попробовал образец 1, и у меня это сработало, спасибо. На самом деле, что именно я сделал, так это зарегистрировал новое приложение, используя регистрацию приложения Azure, и дал необходимые разрешения как VSTS. После выполнения примера я могу получить доступ к остальным API для VSTS.   -  person Shyam    schedule 08.08.2018
comment
@Shyam Что ж, рад узнать, что это помогает, я разместил решение в качестве ответа, вы можете Примите это как ответ. Это может быть полезно другим членам сообщества, читающим эту ветку.   -  person Andy Li-MSFT    schedule 08.08.2018


Ответы (2)


Кажется, это проблема аутентификации, просто проверьте значение authHeader.

Вы можете ссылаться на приведенные ниже примеры для аутентификации с заголовком:

Пример 1 – примеры аутентификации здесь ;

Пример 2 — REST API

Разместите образец авторизации в качестве ссылки здесь:

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;

namespace DeviceProfileSample
{
    public class Program
    {
        //============= Config [Edit these with your settings] =====================
        internal const string vstsCollectionUrl = "https://myaccount.visualstudio.com"; //change to the URL of your VSTS account; NOTE: This must use HTTPS
        internal const string clientId = "872cd9fa-d31f-45e0-9eab-6e460a02d1f1";        //update this with your Application ID from step 2.6 (do not change this if you have an MSA backed account)
        //==========================================================================

        internal const string VSTSResourceId = "499b84ac-1321-427f-aa17-267ca6975798"; //Static value to target VSTS. Do not change


        public static void Main(string[] args)
        {
            AuthenticationContext ctx = GetAuthenticationContext(null);
            AuthenticationResult result = null;
            try
            {
                DeviceCodeResult codeResult = ctx.AcquireDeviceCodeAsync(VSTSResourceId, clientId).Result;
                Console.WriteLine("You need to sign in.");
                Console.WriteLine("Message: " + codeResult.Message + "\n");
                result = ctx.AcquireTokenByDeviceCodeAsync(codeResult).Result;

                var bearerAuthHeader = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                ListProjects(bearerAuthHeader);
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Something went wrong.");
                Console.WriteLine("Message: " + ex.Message + "\n");
            }
        }

        private static AuthenticationContext GetAuthenticationContext(string tenant)
        {
            AuthenticationContext ctx = null;
            if (tenant != null)
                ctx = new AuthenticationContext("https://login.microsoftonline.com/" + tenant);
            else
            {
                ctx = new AuthenticationContext("https://login.windows.net/common");
                if (ctx.TokenCache.Count > 0)
                {
                    string homeTenant = ctx.TokenCache.ReadItems().First().TenantId;
                    ctx = new AuthenticationContext("https://login.microsoftonline.com/" + homeTenant);
                }
            }

            return ctx;
        }

        private static void ListProjects(AuthenticationHeaderValue authHeader)
        {
            // use the httpclient
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(vstsCollectionUrl);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
                client.DefaultRequestHeaders.Add("User-Agent", "VstsRestApiSamples");
                client.DefaultRequestHeaders.Add("X-TFS-FedAuthRedirect", "Suppress");
                client.DefaultRequestHeaders.Authorization = authHeader;

                // connect to the REST endpoint            
                HttpResponseMessage response = client.GetAsync("_apis/projects?stateFilter=All&api-version=2.2").Result;

                // check to see if we have a succesfull respond
                if (response.IsSuccessStatusCode)
                {
                    Console.WriteLine("\tSuccesful REST call");
                    Console.WriteLine(response.Content.ReadAsStringAsync().Result);
                }
                else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                {
                    throw new UnauthorizedAccessException();
                }
                else
                {
                    Console.WriteLine("{0}:{1}", response.StatusCode, response.ReasonPhrase);
                }
            }
        }
    }
}
person Andy Li-MSFT    schedule 08.08.2018

Разве вы не пропускаете аутентификацию,

string credentials = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", token)));
using (HttpClient client = new HttpClient())
                    {
                        client.BaseAddress = new Uri(vstsCollectionUrl);
                        client.DefaultRequestHeaders.Accept.Clear();
                        client.DefaultRequestHeaders.Accept.Add(new              
System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
                        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials)
HttpResponseMessage response = client.GetAsync(uri).Result;
                            response.EnsureSuccessStatusCode();
                            var responseStream = await response.Content.ReadAsStreamAsync();
}

Надеюсь, это поможет.

person Shivaraj    schedule 03.08.2018