使用Azure AD持有令牌

时间:2016-07-13 09:16:43

标签: azure oauth azure-web-sites azure-active-directory bearer-token

我试图访问我在Azure上托管并使用Azure AD保护的API应用程序。

对于API App,我设置了App Service Authentication = Azure Active Directory" Express"管理模式。

在" classic"门户网站我在AD下创建了几个应用程序。一个用于API App,另一个用于Web App。对于Web应用程序,我在其他应用程序的权限下添加了一个条目"对于API应用程序(虽然我不确定我需要这个"访问应用程序所需的用户分配"对于API应用程序是关闭的)。我还为Web App生成了一个密钥。

按照此处给出的示例代码 - https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-oauth2-appidentity ...

我可以使用以下代码成功获取持票人令牌:

private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string appKey = ConfigurationManager.AppSettings["ida:AppKey"];

static string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

private static string ApiId = ConfigurationManager.AppSettings["ApiId"];

private static AuthenticationContext authContext = new AuthenticationContext(authority);
private static ClientCredential clientCredential = new ClientCredential(clientId, appKey);

...

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(ApiId, clientCredential);
    }
    catch (AdalException ex)
    {
        if (ex.ErrorCode == "temporarily_unavailable")
        {
            retry = true;
            retryCount++;
            Thread.Sleep(3000);
        }
    }

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

if (result == null)
    return Request.CreateResponse(HttpStatusCode.InternalServerError, "Could not authenticate against API.");

但是当我使用带有Web应用程序的请求到API应用程序的承载令牌时,我总是得到401未经授权的响应:

StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Date: Wed, 13 Jul 2016 08:43:09 GMT
  Server: Microsoft-IIS/8.0
  WWW-Authenticate: Bearer realm="MY-API-APP-ID-IS-HERE"
  X-Powered-By: ASP.NET
  Content-Length: 58
  Content-Type: text/html
}

这是我用来使401失败的请求的代码:

var apiUri = new Uri(ConfigurationManager.AppSettings["ApiUrl"] + "/api/MethodImCalling");
var client = new RestClient(apiUri.GetLeftPart(UriPartial.Authority));
var request = new RestRequest(apiUri, Method.GET);
request.AddHeader("Authorization", "Bearer " + result.AccessToken);
request.AddParameter("something", somevalue);
var response = client.Execute(request);

if (response.StatusCode != HttpStatusCode.OK)
    return Request.CreateResponse(response.StatusCode); // Relay non-successful response

任何想法我可能做错了或错过了什么?提前谢谢!

我已经在Azure中使用Logic App访问API App而没有问题,但我注意到逻辑应用json中的身份验证凭据包括一个&#34;观众&#34;参数。上面的代码不使用&#34;观众&#34;那么这可能是这个难题的缺失部分,如果是这样,我该如何添加呢?

屏幕截图显示了如何配置Web App以访问API App: enter image description here

1 个答案:

答案 0 :(得分:2)

您获得401响应的原因是您只授予了应用程序委派权限,但您使用的客户端凭据流程需要应用程序权限

您可以更改代码以使用授权代码流,也可以将Web应用程序的应用程序权限授予您的Web API。

要使用授权代码流,您需要更改代码以改为使用AcquireTokenByAuthorizationCodeAsync。

您可以在此处找到有关这两种不同方法的更多信息: https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/#web-application-to-web-api