访问经过身份验证的 Azure API APP

Accessing authenticated Azure API APP

我有一个 Azure API 应用程序,我已将其设置为使用 Azure AD 身份验证。 像这样:

我还有一个控制台应用程序,它为我的 API 应用程序生成了一个客户端 API,如下所示:

如果我在 API 应用程序上禁用身份验证,我可以从我的控制台应用程序调用 API。 如果我启用 Azure AD 身份验证,由于 "not authorized" 异常,客户端无法调用 API,这当然是预期的。

我到处搜索以查找有关如何向 API 提供正确类型的凭据的任何信息。 有一个 client.Credentials 属性 可以是 TokenCredentialsBasicAuthenticationCredentials

如果我有 AD 用户的用户名和密码,通过 Azure AD 验证客户端的正确方法是什么?

我无法找到 任何 与从 Azure SDK 自动生成的 API 客户端相关的文档。

[编辑] 来自@chrisgillum 的回复引出了一篇关于如何做到这一点的文章:

internal class Program
{
    [STAThread]
    private static void Main(string[] args)
    {
        var uri = new Uri("https://ro....azureapp.azurewebsites.net");
        var client = new LearningAzure(uri);
        client.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",
            ServicePrincipal.GetS2SAccessTokenForProdMSA().AccessToken);
        var res = client.Foo.GetById(123);
    }
}


public static class ServicePrincipal
{
    // The _authority is the issuer URL of the tenant.
    private static readonly string _authority = "https://login.windows.net/ro....ouse.onmicrosoft.com";

    // The _resource is the Client ID of the "data web api" AAD app.
    private static readonly string _resource = "b8b0.....8e3623d";

    // The Client ID of the "client" AAD app (i.e. this app).
    private static readonly string _clientId = "d25892.....33a0";

    // The key that was created for the "client" app (i.e. this app).
    private static readonly string _clientSecret = "??????";

    public static AuthenticationResult GetS2SAccessTokenForProdMSA()
    {
        return GetS2SAccessToken(_authority, _resource, _clientId, _clientSecret);
    }


    /// <summary>
    ///     Gets an application token used for service-to-service (S2S) API calls.
    /// </summary>
    private static AuthenticationResult GetS2SAccessToken(string authority, string resource, string clientId,
        string clientSecret)
    {
        // Client credential consists of the "client" AAD web application's Client ID
        // and the key that was generated for the application in the AAD Azure portal extension.
        var clientCredential = new ClientCredential(clientId, clientSecret);

        // The authentication context represents the AAD directory.
        var context = new AuthenticationContext(authority, false);

        // Fetch an access token from AAD.
        var authenticationResult = context.AcquireToken(
            resource,
            clientCredential);
        return authenticationResult;
    }
}

_clientSecret 我如何获得这个? 在我的 Azure AD 中配置的客户端应用程序没有任何生成机密的选项。

已发布的 Web 应用程序可以,但我自定义创建的本机应用程序在配置页面上只有一个客户端 ID。 想法?

如果我没记错的话,这个功能是基于开源项目AutoRest。 可以在 https://github.com/Azure/autorest

找到源代码和文档

在下一页,您可以找到经过身份验证的请求示例:https://github.com/Azure/autorest/blob/master/Documentation/clients-init.md

您可以通过多种不同的方式创建控制台应用程序,该应用程序使用 AAD-protected API 应用程序进行身份验证。这里有一些文档显示使用用户凭据进行身份验证:

https://azure.microsoft.com/en-us/documentation/articles/app-service-api-dotnet-user-principal-auth/

这里是 .NET Web 应用程序(客户端)使用服务主体凭据调用 API 应用程序的示例:https://azure.microsoft.com/en-us/documentation/articles/app-service-api-dotnet-service-principal-auth/。这不完全是您要问的问题,但可能足以帮助您走上正确的轨道。

要在控制台应用程序上获取凭据,如果您提示用户登录,您可以使用他们的凭据来获取令牌。否则,您需要使用客户端应用程序密钥(这是一个客户端应用程序 URI 和匹配 API 密钥)来获取令牌。

Uri aadUri = new Uri(_settings.AadUri);
Uri authorityUri = new Uri(aadUri, _settings.TenantUri);
string authority = authorityUri.ToString();

AuthenticationResult authorizationResult;
var authenticationContext = new AuthenticationContext(authority, new TokenCache());

var clientCredential = new ClientCredential(_settings.ClientId, _settings.AppKey);
authorizationResult = authenticationContext.AcquireToken(_settings.AppIdUri, clientCredential);

您还需要确保您的应用程序 URI 在服务端点的清单中(或以某种方式提供给您的应用程序以 Azure 方式访问 Azure AD)。