0

我在使用aspnet核心構建的組織中使用了web api。我們想發佈一個android應用程序,一個mvc5應用程序和一個aspnet核心mvc6應用程序使用的api。我如何在Azure中配置web api,以便使用它的應用程序不要求登錄。網絡應用程序已經被天藍色保護,但是當我用azure保護web api時,當我向它發出請求時,會得到一個401。我不知道如何在azure中配置應用程序,或者我必須在api中配置的代碼。我讀了很多,但我沒有找到一種方法來實現這一點。我想要的只是登錄我的網絡應用程序,並且Web應用程序開始通過ajax向Web api提問數據。我應該發送ajax請求某種裸機標記,但我不知道我必須在azure和應用程序中執行什麼配置。我希望你能幫助我。Aspnet核心web api使用Azure保護

+0

如果你正在尋找從瀏覽器撥打電話到一個網站,你可能想從這個樣品得到一些想法 - 微軟下面一篇好文章samples/active-directory-angularjs-singlepageapp –

回答

1

在使用Azure AD保護Web API之後,我們需要發送訪問令牌以請求Web API進行授權。當用戶從Web應用程序調用Web API時,我們可以獲取訪問令牌。這裏是收購Web應用程序的令牌,供大家參考代碼:

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"); 
} 

,下面將其使用JwtBearerAppBuilderExtensions到OpenIdConnect承載認證功能添加到一個HTTP應用程序管道用於Web API來驗證的代碼示例令牌:

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

注意:要成功運行此示例中,我們需要修改標題業主爲小寫冠軍所有者在Web應用程序的ToDoController:

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

在這種情況下,用戶只需輸入他們的憑證即可在應用程序中登錄。用戶登錄後,它可以獲取Web API的令牌,而無需用戶再次輸入憑證。這是否適合你的場景? –

+0

@snekkke我不理解:'是不是用戶要求他的憑據......'你想支持什麼樣的場景? –

相關問題