0

Ich habe eine Web-API in meiner Organisation mit Aspnet-Core gebaut. Wir möchten diese API veröffentlichen, um von einer Android-App, einer mvc5-App und einer aspnet core mvc6-App genutzt zu werden. Wie kann ich die Web-API in Blau konfigurieren, damit die Apps, die sie nutzen, nicht zur Anmeldung auffordern? Die Web-Apps, sind bereits mit azurblauen geschützt, aber wenn ich die Web-API mit Azure beschütze, bekomme ich eine 401, wenn ich eine Anfrage an sie stelle. Ich weiß nicht, wie ich die App in Azur oder den Code konfiguriere, den ich in der API konfigurieren muss. Ich habe viel gelesen, aber ich finde keinen Weg, dies zu schaffen. Alles, was ich will, ist in meiner Web-App anmelden, und die Web-App beginnt Daten über Ajax an die Web-API zu fragen. Ich sollte in der Ajax-Anfrage eine Art barer Token einreichen, aber ich weiß nicht, welche Konfiguration ich in azure und in den Apps machen muss. Ich hoffe ihr könnt mir helfen.Aspnet Core Web API geschützt mit Azure

+0

Wenn Sie schauen, Anrufe auf eine Website aus dem Browser zu machen, können Sie einige Ideen aus dieser Probe erhalten möchten: https://github.com/Azure- Samples/active-directory-angularjs-singlepageapp –

Antwort

1

Nachdem Sie die Web-API mit Azure AD geschützt haben, müssen wir sie an ein Zugriffstoken mit der Anforderung der Web-API zur Autorisierung senden. Und wir können das Zugriffstoken erhalten, wenn die Benutzer die Web-API über die Web-App aufrufen. Hier ist der Code des Tokens in der Web-App für Ihre Referenz zu erwerben:

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

Und unten ist der Code Probe, die JwtBearerAppBuilderExtensions verwenden OpenIdConnect Bearer Authentifizierungsfunktionen auf eine HTTP-Anwendung Pipeline für die Web-API hinzufügen die überprüfen token:

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

Das vollständige Codebeispiel können Sie here beziehen.

Hinweis: Um diese Probe erfolgreich auszuführen, müssen wir die Titel und Besitzer in Klein Titel, Besitzer im ToDoController von Web-App ändern:

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

Ich habe dieses Beispiel bereits gesehen. In diesem Fall, wenn die App die API programmatisch aufruft, wird der Benutzer nicht beim ersten Mal nach seinen Anmeldeinformationen gefragt? Das möchte ich vermeiden. – snekkke

+0

In diesem Fall müssen die Benutzer nur ihre Anmeldeinformationen eingeben, um sich in der App anzumelden. Nachdem sich der Benutzer angemeldet hat, kann er das Token für die Web-API erwerben, ohne dass Benutzer den Berechtigungsnachweis erneut eingeben müssen. Passte das zu Ihrem Szenario? –

+0

@snekkke Ich verstehe nicht: "Ist der Benutzer nicht nach seinen Referenzen gefragt ..." Welches Szenario möchten Sie unterstützen? –

Verwandte Themen