0

aspnet 코어로 구축 된 조직에 웹 API가 있습니다. 우리는 안드로이드 app, mvc5 app 및 aspnet core mvc6 app에 의해 소비 될 api를 공개하려고합니다. azure에서 웹 API를 구성하여 해당 앱을 사용하는 사용자가 로그인을 요청하지 않도록하려면 어떻게해야합니까? 웹 응용 프로그램은 이미 푸른 색으로 보호되어 있지만 푸른 색으로 웹 API를 보호하면 요청할 때 401이 표시됩니다. 나는 하늘에서 앱을 구성하는 방법이나 API에서 구성해야하는 코드를 모르겠습니다. 나는 많은 것을 읽었지만 이것을 성취 할 길을 찾지 못한다. 내가 원하는 것은 내 웹 앱에 로그인하고 웹 앱은 아약스를 통해 웹 API에 데이터를 요청하기 시작합니다. 아약스 요청에 어떤 종류의 보증인 토큰을 보내야하지만, 하늘과 앱에서 어떤 설정을해야하는지 알지 못합니다. 네가 나를 도울 수 있기를 바랍니다.Azure로 보호되는 Aspnet 코어 웹 API

+0

당신이, 당신은이 샘플에서 몇 가지 아이디어를 얻을 수도 있습니다 브라우저에서 웹 사이트에 전화를 걸 찾고 있다면 - 아래 마이크로 소프트에서 좋은 기사 Samples/active-directory-anglesjs-singlepageapp –

답변

1

Azure AD로 웹 API를 보호 한 후 권한 부여를 위해 웹 API 요청과 함께 액세스 토큰을 보내야합니다. 사용자가 웹 앱에서 웹 API를 호출하면 액세스 토큰을 얻을 수 있습니다. 아래

public async Task<IActionResult> Index() 
{ 
     AuthenticationResult result = null; 
     List<TodoItem> itemList = new List<TodoItem>(); 

     try 
     { 
      string userObjectID = (User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value; 
      AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userObjectID, HttpContext.Session)); 
      ClientCredential credential = new ClientCredential(Startup.ClientId, Startup.ClientSecret); 
      result = await authContext.AcquireTokenSilentAsync(Startup.TodoListResourceId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId)); 

      // 
      // Retrieve the user's To Do List. 
      // 
      HttpClient client = new HttpClient(); 
      HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, TodoListBaseAddress + "/api/todolist"); 
      request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); 
      HttpResponseMessage response = await client.SendAsync(request); 

      // 
      // Return the To Do List in the view. 
      // 
      if (response.IsSuccessStatusCode) 
      { 
       List<Dictionary<String, String>> responseElements = new List<Dictionary<String, String>>(); 
       JsonSerializerSettings settings = new JsonSerializerSettings(); 
       String responseString = await response.Content.ReadAsStringAsync(); 
       responseElements = JsonConvert.DeserializeObject<List<Dictionary<String, String>>>(responseString, settings); 
       foreach (Dictionary<String, String> responseElement in responseElements) 
       { 
        TodoItem newItem = new TodoItem(); 
        newItem.Title = responseElement["title"]; 
        newItem.Owner = responseElement["owner"]; 
        itemList.Add(newItem); 
       } 

       return View(itemList); 
      } 
      else 
      { 
       // 
       // If the call failed with access denied, then drop the current access token from the cache, 
       //  and show the user an error indicating they might need to sign-in again. 
       // 
       if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized) 
       { 
        var todoTokens = authContext.TokenCache.ReadItems().Where(a => a.Resource == Startup.TodoListResourceId); 
        foreach (TokenCacheItem tci in todoTokens) 
         authContext.TokenCache.DeleteItem(tci); 

        ViewBag.ErrorMessage = "UnexpectedError"; 
        TodoItem newItem = new TodoItem(); 
        newItem.Title = "(No items in list)"; 
        itemList.Add(newItem); 
        return View(itemList); 
       } 
      } 
     } 
     catch (Exception ee) 
     { 
      if (HttpContext.Request.Query["reauth"] == "True") 
      { 
       // 
       // Send an OpenID Connect sign-in request to get a new set of tokens. 
       // If the user still has a valid session with Azure AD, they will not be prompted for their credentials. 
       // The OpenID Connect middleware will return to this controller after the sign-in response has been handled. 
       // 
       return new ChallengeResult(OpenIdConnectDefaults.AuthenticationScheme); 
      } 

      // 
      // The user needs to re-authorize. Show them a message to that effect. 
      // 
      TodoItem newItem = new TodoItem(); 
      newItem.Title = "(Sign-in required to view to do list.)"; 
      itemList.Add(newItem); 
      ViewBag.ErrorMessage = "AuthorizationRequired"; 
      return View(itemList); 
     } 


     // 
     // If the call failed for any other reason, show the user an error. 
     // 
     return View("Error"); 
} 

그리고 검증은 웹 API에 대한 HTTP 응용 프로그램 파이프 라인 OpenIdConnect 무기명 인증 기능을 추가 할 수 JwtBearerAppBuilderExtensions를 사용하는 코드 샘플입니다 : 여기에 참조 용 웹 응용 프로그램에서 토큰을 획득하는 코드입니다 토큰 :

public class Startup 
{ 
     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
     { 
      // Add the console logger. 
      loggerFactory.AddConsole(LogLevel.Debug); 

      // Configure the app to use Jwt Bearer Authentication 
      app.UseJwtBearerAuthentication(new JwtBearerOptions 
      { 
       AutomaticAuthenticate = true, 
       AutomaticChallenge = true, 
       Authority = String.Format(Configuration["AzureAd:AadInstance"], Configuration["AzureAD:Tenant"]), 
       Audience = Configuration["AzureAd:Audience"], 
      }); 
     } 
} 

전체 코드 샘플 here을 참조 할 수 있습니다.

foreach (Dictionary<String, String> responseElement in responseElements) 
{ 
    TodoItem newItem = new TodoItem(); 
    newItem.Title = responseElement["title"]; 
    newItem.Owner = responseElement["owner"]; 
    itemList.Add(newItem); 
} 
+0

이미이 샘플을 보았습니다. 이 경우 앱이 프로그래밍 방식으로 API를 호출하면 사용자가 처음으로 자신의 자격 증명을 요청하지 않았습니까? 그것이 내가 피하고 싶은 것입니다. – snekkke

+0

이 경우 사용자는 앱에 로그인 할 때 자격 증명을 입력하기 만하면됩니다. 사용자가 로그인하면 사용자가 자격 증명을 다시 입력하지 않고 웹 API 토큰을 얻을 수 있습니다. 이게 당신 시나리오에 맞습니까? –

+0

@snekkke 나는 이해하지 못한다. '사용자가 자신의 자격 증명을 요구하지 않았는가 ...'어떤 시나리오를 지원하려고합니까? –

1

당신은 사용할 수 있습니다

참고 : 성공적으로이 샘플을 실행하려면, 우리는 웹 응용 프로그램의 ToDoController에 제목, 소유자를 소문자로 제목소유자을 수정해야 연합 인증을위한 Azure OpenIdConnect. https://github.com/Azure- :

Calling a web API in a web app using Azure AD and OpenID Connect

관련 문제