2

我正在尝试使用Microsoft.AspNetCore.TestHostAzure Active Directory 保护的 WebAPI 进行测试。我可以使用 PostMan 从 Azure AD 的 oauth2/token 端点获取不记名令牌,并在“/api/Values”上调用 HTTP GET。但是,当我对 TestHost 服务器执行相同操作时,我总是会收到 401 未经授权的错误。

我已将我的 TestHost 配置为使用内置于我的 ASP.NET Core WebAPI 项目中的 Startup 类(这是在您使用标准模板并选择 Azure Active Directory 作为身份验证提供程序时默认生成的类)。

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

我尝试了两种附加不记名令牌的方法。

第一种方法,使用我从 TestServer 生成的客户端的 DefaultRequestHeaders:

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;
}

此代码生成一个令牌。它正在产生与我正在做的相同的邮递员职位。

使用邮递员获取令牌

使用相同的技术在 IIS Express 托管的 WebAPI 上执行 HTTP GET 是可行的。

带有承载令牌的 WebAPI 调用也可以工作

我怀疑 AspNetCore.TestHost 不支持这一点,或者我没有做任何事情来正确配置它以点亮我在 IIS Express 上调试时正在工作的 Azure Active Directory 配置,但文档非常简单。

4

0 回答 0