如何配置ASP.Net Core 2.0 API以将Azure AD用作身份提供程序

问题描述 投票:0回答:1

好的,所以我在VS2017中为ASP.Net Core 2.0 API创建了一个新项目。我已经设置了Azure AD并在向导上设置了一个新项目,我选择了Change Authentication并选择了“Work or School accont”,然后输入我的Azure AD的名称(即mycompany.onmicrosoft.com)。项目已创建,我可以在Startup.cs中看到此代码的添加

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddAzureAdBearer(options => Configuration.Bind("AzureAd", options));

        services.AddMvc();
    }

我可以看到添加到appSettings.json文件的设置

"AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "mycompany.onmicrosoft.com",
    "TenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}, 

其中TenentID是Azure AD的目录ID,ClientID是新创建的API的ApplicationID值,因为它现在已在Azure AD中注册。

这一切都有道理。

但是,如果我在VS2017中运行该项目然后导航到https://localhost:44348/api/values loction,我将获得401 Unauthorized。

那部分我错过了我必须在Azure中以某种方式注册我的https://localhost:44348浏览器实例,以便将其识别为我的测试的批准客户端应用程序。但我不清楚在哪里这样做。我是否只是在我的Azure AD应用注册中注册https://localhost:44348我应该在Azure AD中的Anew API项目的应用注册中生成一个密钥,并以某种方式将该密钥作为秘密传递给我的auth标头?

如果我想用邮递员测试这个怎么办?我该怎么办?我是否必须以某种方式在Azure AD中注册邮递员?

我查看了许多Google页面,并且有大量示例显示如何从网页进行交互式登录,然后在Azure AD中注册该网页登录URL,而不是在仅尝试从VS2017测试API时如何执行此操作调试或邮差。

我怎么做?

编辑 - 阅读评论后,我创建了一个控制台应用程序,并在Azure AD应用程序注册中注册并创建了一个密钥。我在这里为其他任何可能试图理解这个进程服务器到服务器OAUTH2进程的人提供它。

感谢this GitHub repo在下面的代码设计中的帮助;

这是控制台应用程序代码

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Configuration;
using System.Globalization;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Script.Serialization;

namespace API.TestConsole
{
    class Program
    {

        /// <summary>
        /// The AAD Instance is the instance of Azure.
        /// </summary>
        /// <remarks>
        /// Example: https://login.microsoftonline.com/{0}
        /// </remarks>
        private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];

        /// <summary>
        //  The Tenant is the Directory ID of the Azure AD tenant in which this application is registered.
        /// </summary>
        private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];

        /// <summary>
        /// The Client ID is used by this application to uniquely identify itself to Azure AD.
        /// </summary>
        /// <remarks>
        /// This value is obtained when this application is registered in Azure AD
        /// </remarks>
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];

        /// <summary>
        //  The App Key is a credential used by this application to authenticate to Azure AD.
        /// </summary>
        /// <remarks>
        /// This value is generated when this application is registered in Azure AD and assigned a key
        /// </remarks>
        private static string appKey = ConfigurationManager.AppSettings["ida:AppKey"];

        /// <summary>
        //  The Authority is the sign-in URL of the tenant.
        /// </summary>
        /// <remarks>
        /// This is a string combination of the aadInstance and the tenant
        /// </remarks>
        static string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

        /// <summary>
        /// The ApplicationID of the evsApi service in Azure
        /// </summary>
        private static string apiResourceId = ConfigurationManager.AppSettings["api:ApiResourceId"];

        /// <summary>
        /// The base URL address of the Api service
        /// </summary>
        private static string apiBaseAddress = ConfigurationManager.AppSettings["api:ApiBaseAddress"];


        private static HttpClient httpClient = new HttpClient();
        private static AuthenticationContext authContext = null;
        private static ClientCredential clientCredential = null;

        static void Main(string[] args)
        {

            // As a test, call the test Api, values endpoint 10 times with a short delay between calls
            authContext = new AuthenticationContext(authority);
            clientCredential = new ClientCredential(clientId, appKey);

            for (int i = 0; i < 10; i++)
            { 
                Thread.Sleep(3000);
                GetValues().Wait();
            }
            Console.WriteLine("Press ENTER to exit.");
            Console.ReadLine();
        }

        static async Task GetValues()
        {
            // Get an access token from Azure AD using client credentials.
            // If the attempt to get a token fails because the server is unavailable, retry twice after 3 seconds each.
            AuthenticationResult result = null;
            int retryCount = 0;
            bool retry = false;

            do
            {
                retry = false;
                try
                {
                    // ADAL includes an in memory cache, so this call will only send a message to the server if the cached token is expired.
                    result = await authContext.AcquireTokenAsync(apiResourceId, clientCredential);
                }
                catch (AdalException ex)
                {
                    if (ex.ErrorCode == "temporarily_unavailable")
                    {
                        retry = true;
                        retryCount++;
                        Thread.Sleep(3000);
                    }

                    Console.WriteLine(
                        String.Format($"An error occurred while acquiring a token\nTime: " +
                        $"{DateTime.Now.ToString()}\nError: {ex.ToString()}\nRetry: {retry.ToString()}\n"));
                }

            } while ((retry == true) && (retryCount < 3));

            if (result == null)
            {
                Console.WriteLine("Canceling attempt to contact the test API service.\n");
                return;
            }

            // Add the access token to the authorization header of the request.
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

            // Call the values endpoint in the test API service. This is an HTTP GET.
            Console.WriteLine("Retrieving values from Values endpoint at {0}", DateTime.Now.ToString());
            HttpResponseMessage response = await httpClient.GetAsync(apiBaseAddress + "/api/values");

            if (response.IsSuccessStatusCode)
            {
                // Read the response and output it to the console.
                string s = await response.Content.ReadAsStringAsync();
                Console.WriteLine($"Values Result:  {s}\n");
            }
            else
            {
                Console.WriteLine("Failed to retrieve Values\nError:  {0}\n", response.ReasonPhrase);
            }
        }

    }
}

这是App.Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
  <appSettings>
    <add key="ida:AADInstance" value="https://login.microsoftonline.com/{0}" />

    <!-- This is the Directory ID value of the Azure AD -->
    <add key="ida:Tenant" value="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" />

    <!-- This is the Application ID value of this test console application as it is 
       registered in the Azure AD app registration in the portal directory -->    
    <add key="ida:ClientId" value="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" />

    <!-- This is the Key value of this test console application, as it is 
       generated in the keys section for "Test Console Key" in the Azure AD app registration 
       for this test console application in the portal directory -->
    <add key="ida:AppKey" value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />

    <!-- This is the Application ID value of the test api application as it is 
       registered in the Azure AD app registration in the portal directory -->
    <add key="api:apiResourceId" value="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" />

    <!-- This is the custom domain URL assigned to the test app service in the Azure   
        portal -->
    <add key="api:apiBaseAddress" value="https://testapi.mycompany.com" />
  </appSettings>

</configuration>
oauth-2.0 azure-active-directory asp.net-core-2.0 asp.net-core-webapi azure-app-service-envrmnt
1个回答
1
投票

简而言之,您需要一个访问令牌。

你如何获得访问令牌?通过OAuth Client Credentials等认证流程:https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service

或者您可能需要使用OpenID Connect:https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-openid-connect-code

客户端凭据将作为应用程序进行调用,而OIDC(以及其他一些流程)允许您以用户身份调用API。

除非您添加一些权限,否则您必须以用户身份进行呼叫:https://joonasw.net/view/defining-permissions-and-roles-in-aad

无论如何,您必须注册将调用API的应用程序,并授予其访问API的权限。

© www.soinside.com 2019 - 2024. All rights reserved.