【问题标题】:Web Application and API AzureAD authentication flow ASP.NET CoreWeb 应用程序和 API AzureAD 身份验证流程 ASP.NET Core
【发布时间】:2019-01-14 03:22:02
【问题描述】:

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

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

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

问题 1:这是正确的身份验证流程吗?对我来说,这似乎是双重身份验证,因为首先我在前端对自己进行身份验证,当 Webapp 需要一些数据时,我需要在后端再次对自己进行身份验证。使用了相同的 Azure AD 租户,你怎么看?

接下来看起来很“丑陋”的一点是获取一些数据的过程。在示例中,首先请求某些数据时,将请求令牌,然后再请求数据。但在我看来,有很多样板。下面的示例代码仅适用于所有 ToDo 项目的一个请求。

// 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:如果第一季度的流程正确,是否有一种“不那么丑陋”的方法来访问数据?

【问题讨论】:

    标签: c# authentication asp.net-core asp.net-core-mvc azure-active-directory


    【解决方案1】:

    我找到了一个合适的解决方案来解决这个问题。

    我刚刚使用了这个例子中的方法multitenant-saas-guidance,它就像魅力一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 2019-06-30
      • 2017-08-31
      • 2020-07-27
      相关资源
      最近更新 更多