![](/img/trans.png)
[英]Asp.net Core 2.1 Pass AzureAd Authentication Bearer to Web Api which uses [Authorize]
[英]Web Application and API AzureAD authentication flow ASP.NET Core
我目前對如何實現身份驗證/授權流程感到困惑。
我正在開發兩個應用程序,一個是前端/ Web應用程序,另一個是后端/ API,都使用ASP.NET Core。 目標是使用AzureAD並使用域中的用戶/組。 我已經在兩個應用程序上都實現了身份驗證,並且能夠基於登錄狀態登錄和限制內容。
作為參考,我從微軟開發人員那里舉了這個例子。 我應該做的正是這件事。 有一個WebApp和API。 使用的認證流程是授權碼流程 。 首先,用戶需要登錄,然后,當需要從API請求一些數據時,將請求訪問令牌。
問題1:這是正確的身份驗證流程嗎? 對我來說,這似乎是雙重身份驗證,因為首先我在前端對自己進行身份驗證,當Webapp需要一些數據時,我需要在后端再次進行身份驗證。 使用相同的Azure AD租戶,那么您對此有何看法?
接下來的一點看起來非常“丑陋”是獲取一些數據的過程。 在該示例中,當首先請求某些數據時,將請求令牌,然后請求數據。 但是我認為有很多樣板。 對於所有待辦事項中的一個請求,僅需以下示例代碼。
// GET: /<controller>/
public async Task<IActionResult> Index()
{
AuthenticationResult result = null;
List<TodoItem> itemList = new List<TodoItem>();
try
{
// Because we signed-in already in the WebApp, the userObjectId is know
string userObjectID = (User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
// Using ADAL.Net, get a bearer token to access the TodoListService
AuthenticationContext authContext = new AuthenticationContext(AzureAdOptions.Settings.Authority, new NaiveSessionCache(userObjectID, HttpContext.Session));
ClientCredential credential = new ClientCredential(AzureAdOptions.Settings.ClientId, AzureAdOptions.Settings.ClientSecret);
result = await authContext.AcquireTokenSilentAsync(AzureAdOptions.Settings.TodoListResourceId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
// Retrieve the user's To Do List.
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, AzureAdOptions.Settings.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);
}
//
// 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)
{
return ProcessUnauthorized(itemList, authContext);
}
}
catch (Exception)
{
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");
}
問題2:如果Q1中的流程正確,是否存在“不太丑陋”的方法來訪問數據?
我找到了解決此問題的合適方法。
我只是在此示例中使用了多租戶saas指導的方法 ,它的工作原理就像魅力。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.