2

我试图访问我在Azure上托管并使用Azure AD进行保护的API应用程序。使用Azure AD承载令牌对API应用程序进行Web应用程序验证

对于API应用程序,我已经设置了App Service身份验证= Azure Active Directory“Express”管理模式。

在“经典”门户网站中,我创建了AD下的几个应用程序。一个用于API应用程序,另一个用于Web应用程序。对于Web应用程序,我在API应用程序的“对其他应用程序的权限”下添加了一个条目(尽管我不确定我是否需要此API API,因此“访问应用程序所需的用户分配”关闭)。我还为Web应用程序生成了一个密钥。

继此处给出的示例代码 - 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中的逻辑应用程序访问API应用程序没有问题,但我注意到逻辑应用程序json中的身份验证凭证包含“受众”参数。上面的代码不使用“观众”,所以这可能是谜题的缺失部分,如果是的话,我该如何添加它?

屏幕截图显示的Web应用程序如何被配置为访问API应用程序: enter image description here

+1

您能也分享你如何配置你的授权API的细节? –

+0

@PhilippeSignoret - 我正在使用App Service Authenication = Azure Active Directory“Express”管理模式(也会增加问题)。这是你之后的细节吗?不确定要提供哪些其他细节。干杯。 – Gavin

+0

示例代码在部署到Azure之前是否可以在您的本地上正常工作?如果访问令牌不允许您访问您的API,我建议您使用JWT解码工具来分析令牌,这里是JWT解码的网页:https://jwt.io/。 –

回答

2

你得到一个401响应的原因是,你只授予您的应用程序委托权限,但您使用的是客户端凭据流程,需要应用程序权限

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

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

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

+0

谢谢指针Saca。我正在尝试根据您所指示的内容实施解决方案。因为有一点点可以把我的头包裹起来,所以学习曲线的位置很小。一旦我明白了,我会将其标记为答案。我发现了一些来自微软的代码示例,但我想我会尝试解决“或者将应用程序权限从您的Web应用程序授予您的Web API”选项,因为这听起来像纯粹的配置。 – Gavin

+0

我真的很苦恼。我确定这很简单,但我在哪里“将应用程序权限从您的Web应用程序授予您的Web API”? – Gavin

+0

看起来像我的问题可能是相同的这些 - http://stackoverflow.com/questions/38262085/azure-ad-api-request-401-unauthorized和http://stackoverflow.com/questions/37404286/azure-广告-HTTP-1-1-401不正当窗口服务 – Gavin

相关问题