AspNetCore.TestHost + Azure Active Directory (Part I)

I have been evaluating new practices for implementing Integration Testing WebAPIs and I’ve been trying to use TestHost to test a WebAPI that I have secured with Azure Active Directory. I am able to use PostMan to obtain a bearer token from Azure AD’s oauth2/token endpoint and call HTTP GET on ‘/api/Values’. However, when I do the same to the TestHost Server I always get a 401 unauthorized error.

I’ve configured my TestHost to use the Startup class that is built into my ASP.NET Core WebAPI project (it’s the one that is generated by default when you use the standard template and select Azure Active Directory as your authentication provider).

 Server = new TestServer(
 new WebHostBuilder()  .UseStartup<Startup>()  );

I’ve tried two methods of attaching the bearer token.

First approach, using the DefaultRequestHeaders of the client I generate from the TestServer:

Client = Server.CreateClient(); Client.DefaultRequestHeaders.Add("Authorization", "Bearer " + AccessToken);

Second approach is attaching the header to the request itself:

 var req = _sut.Server.CreateRequest("/api/Values").AddHeader("Authorization", "Bearer " + _sut.AccessToken);  var response = await req.GetAsync();

However, both of these get a 401 unauthorized.

I am using the same method to obtain a token as I do in PostMan, except in code in my automated unit tests.

 public static string GetAccessToken()  {  string token = null;  // Constants  var tenant = "MY_TENANT_HERE.onmicrosoft.com";  var serviceUri = "https://MY_TENTANT_HERE.com/WebApplicationAAD";  var clientID = "a1d51587-bf4c-4915-b588-8df1d9fd7ac9"; // this is the Application ID for the Native App in Azure AD  var userName = "integration_test@MY_TENANT_HERE.com";  var password = "THE_PASSWORD_FOR_THE_TEST_ACCOUNT";  var appClientId = "d476fd33-4cfc-4aeb-9d4d-ea4978af5660"; // this is the Application ID for the Web API app in Azure AD  using (var webClient = new WebClient())  {  var requestParameters = new NameValueCollection();
 requestParameters.Add("grant_type", "password");  requestParameters.Add("client_id", clientID);  requestParameters.Add("username", userName);  requestParameters.Add("password", password);  requestParameters.Add("resource", appClientId);  //requestParameters.Add("scope", "openid");  var url = $"https://login.microsoftonline.com/" + tenant + "/oauth2/token";  var responsebytes = webClient.UploadValues(url, "POST", requestParameters);  var responsebody = Encoding.UTF8.GetString(responsebytes);  var jsonresult = JObject.Parse(responsebody);  token = (string)jsonresult["access_token"];  }  return token;  }

This code produces a token. It is producing the same postman post that I am doing.

 

Doing HTTP GET on the IIS Express hosted WebAPI using the same technique WORKS.

 

I suspect either AspNetCore.TestHost does not support this or I am not doing something to properly configure it to light up the Azure Active Directory config that is working when I debug on IIS Express but documentation is extremely light.

In Part II, I’ll show you how I overcame this challenge and why I was ultimately seeing this behavior.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s