Web 应用程序和 API AzureAD 身份验证流 ASP.NET 核心



我目前对如何实现身份验证/授权流程感到困惑。

我正在开发两个应用程序,一个是前端/Web应用程序,另一个是后端/API,两者都带有 ASP.NET Core。目标是使用 AzureAD 并使用域中的用户/组。我已经在两个应用程序上实施了身份验证,并且我能够根据登录状态登录和限制内容。

作为参考,我从微软开发人员那里获得了这个例子。应该有我想做的。有一个WebApp和API。使用的身份验证流是授权代码流。首先,用户需要登录,然后当需要从API请求某些数据时,将请求访问令牌。

问题 1:这是正确的身份验证流程吗?对我来说,这似乎是双重身份验证,因为首先我在前端对自己进行身份验证,当 Web 应用程序需要一些数据时,我需要在后端再次进行身份验证。使用相同的 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 指南,它的工作原理就像魅力一样。

最新更新