Поддерживает ли AspNetCore.TestHost Azure Active Directory?
Я пытаюсь использовать Microsoft.AspNetCore.TestHost
проверить WebAPI, который я защитил с помощью Azure Active Directory. Я могу использовать PostMan для получения токена-носителя от конечной точки oauth2/token Azure AD и вызова HTTP GET для "/api/Values". Однако, когда я делаю то же самое с сервером TestHost, я всегда получаю 401 несанкционированную ошибку.
Я настроил свой TestHost для использования класса Startup, встроенного в мой проект ASP.NET Core WebAPI (он создается по умолчанию, когда вы используете стандартный шаблон и выбираете Azure Active Directory в качестве поставщика проверки подлинности).
Server = new TestServer(
new WebHostBuilder()
.UseStartup<Startup>()
);
Я попробовал два способа прикрепления токена на предъявителя.
Первый подход, используя DefaultRequestHeaders клиента, который я генерирую из TestServer:
Client = Server.CreateClient();
Client.DefaultRequestHeaders.Add("Authorization", "Bearer " + AccessToken);
Второй подход - присоединение заголовка к самому запросу:
var req = _sut.Server.CreateRequest("/api/Values").AddHeader("Authorization", "Bearer " + _sut.AccessToken);
var response = await req.GetAsync();
Тем не менее, оба они получают 401 несанкционированный.
Я использую тот же метод для получения токена, что и в PostMan, за исключением кода в моих автоматических модульных тестах.
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;
}
Этот код производит токен. Он производит тот же пост почтальона, что и я.
Выполнение HTTP GET на размещенном в IIS Express WebAPI с использованием той же методики РАБОТАЕТ.
Я подозреваю, что либо AspNetCore.TestHost не поддерживает это, либо я не делаю что-то для его правильной настройки для отображения конфигурации Azure Active Directory, которая работает при отладке в IIS Express, но документация чрезвычайно проста.