I'm attempting to access an API App I have hosted on Azure and secured with Azure AD.
For the API App I've set App Service Authentication = Azure Active Directory "Express" management mode.
In the "classic" portal I've created a couple of applications under AD. One for the API App and another for the Web App. And for the Web App I've added an entry under "permissions to other applications" for the API App (though I'm not sure I need this as "user assignment required to access app" is off for the API App). I've also generated a key for the Web App.
Following the example code given here - https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-oauth2-appidentity ...
I can successfully obtain a bearer token using the following code:
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.");
But when I use the bearer token with with the request from the Web App to the API App I always get a 401 unauthorized response:
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
}
This is the code I'm using to make the request that's failing with a 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
Any ideas what I might be doing wrong or am missing? Thanks in advance!
I already have Logic App in Azure accessing the API App without issue, but I note that the authentication credentials in the logic app json include an "audience" parameter. The code above does not use an "audience" so could this be the missing part of the puzzle, and if so, how do I add it?
Screenshot showing how Web App has been configured to access API App: