【问题标题】:Using Oauth to protect WebAPI with Azure active directory使用 Oauth 通过 Azure 活动目录保护 WebAPI
【发布时间】:2017-10-25 05:55:11
【问题描述】:

我已经浏览了有关使用 Oauth 在线保护 Azure Active Directory 中的 WebAPI 的所有教程。但不幸的是,它们都不能工作。

我使用的是 VS 2017,我的项目是 .net core。

到目前为止,我尝试过的是:

public void ConfigureServices(IServiceCollection services)
{
     services.AddMvc();
     ervices.AddAuthentication(); // -----------> newly added
 } 

在“配置”中,我添加了:

app.UseJwtBearerAuthentication(new JwtBearerOptions
{
     AutomaticAuthenticate = true,
     AutomaticChallenge = true,
     Authority = String.Format(Configuration["AzureAd:AadInstance"], Configuration["AzureAD:Tenant"]),
     Audience = Configuration["AzureAd:Audience"],         
 });

这是我的配置:

"AzureAd": {
    "AadInstance": "https://login.microsoftonline.com/{0}",
    "Tenant": "tenantname.onmicrosoft.com",
    "Audience": "https://tenantname.onmicrosoft.com/webapiservice"
  }

我已经在我的 AAD 上注册了这个“webapiservice”(链接是:http://webapiservice.azurewebsites.net)。

另外,为了访问这个 web api 服务,我创建了一个 webapi 客户端“webapiclient”,它也是一个 web api,并且还在我的 AAD 上注册了它并请求访问“webapiservice”的权限。 webapi客户端链接为:http://webapiclient.azurewebsites.net

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://webapiservice.azurewebsites.net/");
//is this uri correct? should it be the link of webapi service or the one of webapi client?

HttpResponseMessage response = client.GetAsync("api/values").Result;
if (response.IsSuccessStatusCode)
{
     var result = response.Content.ReadAsAsync<IEnumerable<string>>().Result;
     return result;
}
else
{
     return new string[] { "Something wrong" };
} 

所以理论上,我应该从 webapiservice 收到正确的结果。但我总是收到“有问题”。

我这里有什么遗漏吗?

【问题讨论】:

  • 您没有将身份验证令牌添加到请求中?
  • 什么意思?不是AAD管理的吗?
  • 您的应用必须获取它。它可以使用各种方法来做到这一点,例如,它可以使用客户端 ID 和机密向 AAD 证明它是这个应用程序,并需要该 API 的令牌。然后,AAD 会给您一个令牌,您可以将其附加到请求中。
  • @juunas 那是我缺少的部分。如何从 AAD 检索访问令牌?你有一个例子来说明这一点吗?

标签: azure azure-active-directory asp.net-core-webapi


【解决方案1】:

您需要来自 Azure AD 的访问令牌

GitHub 上有很多很好的示例应用程序,这里有一个用于守护程序应用程序的示例:https://github.com/Azure-Samples/active-directory-dotnet-daemon/blob/master/TodoListDaemon/Program.cs#L96

AuthenticationResult authResult = await authContext.AcquireTokenAsync(todoListResourceId, clientCredential);

此应用获取访问令牌及其客户端 ID 和 API 的客户端密码。您可以在您的情况下采用类似的方法。例如,对于 Azure AD Graph API,您可以将 todoListResourceId 替换为 "https://graph.windows.net/",或者对于 Microsoft Graph API 替换 "https://graph.microsoft.com/"。这是您想要为其获取令牌的 API 的标识符。

这就是它在 AAD 中的工作方式。您想要访问 API,您需要从 AAD 获得该访问权限。在成功的响应中,您将返回一个访问令牌,您必须将其作为标头附加到 HTTP 调用:

Authorization: Bearer accesstokengoeshere......

现在,如果您正在构建一个 Web 应用程序,您可能希望做一些不同的事情,因为您现在以客户端应用程序而不是用户的身份访问 API。如果您想进行委派呼叫,则需要使用例如授权码流程,您可以在其中向用户显示浏览器,将他们重定向到正确的地址,然后他们会被发送回您的应用进行登录。

【讨论】:

    【解决方案2】:

    要调用受 azure ad 保护的 web api,您应该使用承载方案在授权标头中传递此获取的访问令牌:

    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
    

    【讨论】:

    • 您想详细说明一下吗?如何在您的示例中获取“authResult”?
    • 您可以使用 openid connect/oauth2.0 身份验证协议和 azure ad 来获取受 AAD 保护的资源的访问令牌,请查看 Authentication Scenarios for Azure ADthese code samples
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 2013-02-15
    • 2019-05-20
    相关资源
    最近更新 更多