2017-03-29 3 views
0

나는 Azure Scheduler를 호출하여 토큰을 얻은 다음 그 토큰을 사용하여 편안한 전화를 걸기 위해 사용되는 코드가 있습니다. 치료를해라.Azure web api Unauthorized 401

그래서 새 앱에 코드를 채택하기로 결정했으나 이번에는 내 웹 API를 하늘빛으로 호스팅했습니다. API가 Active Directory에 등록되었습니다. 비밀 키 등을 만들었습니다. 정적 HTTP 클라이언트를 initiliaze하면 토큰을 성공적으로 가져옵니다.

하지만 auth 용 토큰을 사용하여 API를 호출하면 응답이 401 "인증되지 않음"이며, 아래 코드가 있습니다.

public static class SchedulerHttpClient 
{ 
    const string SPNPayload = "resource={0}&client_id={1}&grant_type=client_credentials&client_secret={2}"; 

    private static Lazy<Task<HttpClient>> _Client = new Lazy<Task<HttpClient>>(async() => 
    { 
     string baseAddress = ConfigurationManager.AppSettings["BaseAddress"]; 
     var client = new HttpClient(); 
     client.BaseAddress = new Uri(baseAddress); 
     await MainAsync(client).ConfigureAwait(false); 
     return client; 
    }); 

    public static Task<HttpClient> ClientTask => _Client.Value; 

    private static async Task MainAsync(HttpClient client) 
    { 
     string tenantId = ConfigurationManager.AppSettings["AzureTenantId"]; 
     string clientId = ConfigurationManager.AppSettings["AzureClientId"]; 
     string clientSecret = ConfigurationManager.AppSettings["AzureClientSecret"]; 

     string token = await AcquireTokenBySPN(client, tenantId, clientId, clientSecret).ConfigureAwait(false); 

     client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); //TODO ssmith: const or localization 
    } 

    private static async Task<string> AcquireTokenBySPN(HttpClient client, string tenantId, string clientId, string clientSecret) 
    { 
     var payload = String.Format(SPNPayload, 
            WebUtility.UrlEncode(ConfigurationManager.AppSettings["ARMResource"]), 
            WebUtility.UrlEncode(clientId), 
            WebUtility.UrlEncode(clientSecret)); 

     var body = await HttpPost(client, tenantId, payload).ConfigureAwait(false); 
     return body.access_token; 
    } 

    private static async Task<dynamic> HttpPost(HttpClient client, string tenantId, string payload) 
    { 
     var address = String.Format(ConfigurationManager.AppSettings["TokenEndpoint"], tenantId); 
     var content = new StringContent(payload, Encoding.UTF8, "application/x-www-form-urlencoded"); 
     using (var response = await client.PostAsync(address, content).ConfigureAwait(false)) 
     { 
      if (!response.IsSuccessStatusCode) 
      { 
       Console.WriteLine("Status: {0}", response.StatusCode); 
       Console.WriteLine("Content: {0}", await response.Content.ReadAsStringAsync().ConfigureAwait(false)); 
      }//TODO: start removing tests 

      response.EnsureSuccessStatusCode(); 

      return await response.Content.ReadAsAsync<dynamic>().ConfigureAwait(false); 
     } 
    } 
} 

위의 코드는 httpclient를 만들고 권한을 부여하는 클래스입니다.

public virtual async Task<T> GetAsync(string apiURL) 
    { 
     try 
     { 
      _client = await SchedulerHttpClient.ClientTask; 
      var response = await _client.GetAsync(apiURL); 
      response.EnsureSuccessStatusCode(); 
      var responseContent = await response.Content.ReadAsAsync<T>().ConfigureAwait(false); 

      return responseContent; 
     } 
     catch (Exception e) 
     { 
      return default(T); 
     } 
    } 

위의 코드는 단순히 결과를 얻을 수 있는지 테스트하기 위해 간단하게 테스트 한 것입니다. 그러나 명시된 바와 같이 401을 반환합니다.

제 질문은 제 승인 코드가 잘못된 것입니까?

<add key="ARMResource" value="https://management.core.windows.net/" /> 
<add key="TokenEndpoint" value="https://login.windows.net/{0}/oauth2/token" /> 
<add key="BaseAddress" value="https://mysite.azurewebsites.net" /> 

답변

0

이 특정 문제는 웹 API의 경우 잘못된 "ARMresource"로 인해 클라이언트 ID로 변경해야한다고 생각됩니다.

Source of answer

그러나 나는 내 SPNPayload 문자열에서 완전히 자원을 생략 할 수 있습니다 생각, 내 문제가 동일 보인다.