【问题标题】:Accessing authenticated Azure API APP访问经过身份验证的 Azure API APP
【发布时间】:2015-12-28 13:40:41
【问题描述】:

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

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

如果我在 API APP 上禁用身份验证,我可以从我的控制台应用程序调用 API。 如果我启用 Azure AD 身份验证,由于“未授权”异常,客户端无法调用 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 中配置的客户端应用程序没有任何选项来生成密钥。

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

【问题讨论】:

    标签: api azure azure-active-directory azure-api-apps


    【解决方案1】:

    要在控制台应用程序上获取凭据,如果您提示用户登录,您可以使用他们的凭据来获取令牌。否则,您需要使用客户端应用程序密钥(即客户端应用程序 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 AD 的 azure 访问权限)。

    【讨论】:

    • 哦,如果不清楚的话,ClientId 是来自门户的 GUID。
    • 谢谢,这一切都解决了,我现在可以通过代码和提示同时使用用户 ID/密码进行身份验证......谢谢!
    • 太好了,乐于助人。
    【解决方案2】:

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

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

    【讨论】:

    • 似乎没有关于如何对 Azure AD 进行实际身份验证的信息。顾名思义,BasicAuthenticationCredentials 用于基本身份验证.. :-/
    【解决方案3】:

    您可以通过多种不同的方式创建控制台应用,该应用使用受 AAD 保护的 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/。这并不完全是您要问的问题,但可能足以帮助您走上正轨。

    【讨论】:

    • 那篇文章是关于浏览器中AngularJS/JS客户端的SSO
    • @RogerAlsing 啊,我的错。我认为下一个最好的事情是尝试这篇文章,它显示了一个 .NET Web 应用程序(客户端)调用一个 API 应用程序。 azure.microsoft.com/en-us/documentation/articles/…
    • 这似乎是在正确的轨道上,但是,仍然得到未经授权的异常。查看更新的问题,我已经添加了文章中的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 2016-04-07
    • 2019-01-29
    • 2016-01-15
    • 1970-01-01
    相关资源
    最近更新 更多