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

时间:2015-12-28 13:40:41

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

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

enter image description here

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

enter image description here

如果我在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。 想法?

3 个答案:

答案 0 :(得分: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方式访问Azure AD)。

答案 1 :(得分:0)

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

找到

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

答案 2 :(得分:0)

有多种不同的方法可以创建一个控制台应用程序,该应用程序使用受AAD保护的API应用程序进行身份验证。以下是一些显示使用用户凭据进行身份验证的文档:

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

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