2

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: enter image description here

6
  • 1
    Can you also share details about how you've configured your API for authorization? Commented Jul 13, 2016 at 12:24
  • @PhilippeSignoret - I'm using App Service Authenication = Azure Active Directory "Express" management mode (will add to question also). Is this the detail you're after? Not sure what other detail to provide. Cheers. Commented Jul 14, 2016 at 1:34
  • Does the sample code work fine on your local before deploy to Azure? If the access token does not allow you to access your API, I would suggest you use JWT decoded tool to analyze the token, here is the JWT decoded web page: jwt.io. Commented Jul 14, 2016 at 8:45
  • @Jambor-MSFT - no unfortunately the code isn't working locally or on Azure. Cheers. Commented Jul 14, 2016 at 10:24
  • Can you add a screenshot of how you set up you Web App's "Permissions to oter Applications"? Commented Jul 16, 2016 at 4:45

1 Answer 1

2

The reason you are getting a 401 response is that you've only granted your application Delegated Permissions, yet you are using the client credentials flow which requires Application Permissions.

You can either change your code to use the Authorization Code flow or grant application permissions from your web app to your web API.

To use the Authorization Code flow you'd need to change your code to use AcquireTokenByAuthorizationCodeAsync instead.

You can find more information about these two different approaches here: https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/#web-application-to-web-api

Sign up to request clarification or add additional context in comments.

3 Comments

Thank for the pointer Saca. I'm trying to implement a solution based on what you've indicated. Bit of a learning curve as there's a little bit to wrap my head around. Once I've figured it out I'll mark it as the answer. I've found a few code examples from Microsoft to explore but I think I'll try and fire out the "or grant application permissions from your web app to your web API" option as this sounds like purely configuration.
I'm really struggling with this. I'm sure it's something simple, but where do I "grant application permissions from your web app to your web API"?
Looks like my issue might be the same as these - stackoverflow.com/questions/38262085/… and stackoverflow.com/questions/37404286/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.