使用AAD身份验证从具有MSI的App Service向另一个App Service API发出HTTP请求

时间:2019-11-22 13:38:11

标签: c# azure authentication azure-active-directory azure-web-app-service

我想做的是使用MSI身份从App Service 1( MainWebApp )到App Service 2( AadAuthenticationApiOne-Dev )进行授权呼叫来自App Service 1,该服务应获得App Service 2的肯定授权。

虽然这应该不太困难,但我仍然无法使该流程正常运行。可能是因为我在某处缺少某些复选框。我已经尝试了多种方法,但是通过遵循Joonas Westlin's blogpost on the matter重新开始。

这意味着我具有我的 MainWebApp 的身份(对象ID:bf00c7e8-b14b-4fe5-b768-da255026ff17)和我的第二个应用程序服务的应用程序注册,称为 AadAuthenticationApiOne (ObjectId -9863b99a-6f28-4053-8a47-050f2b6da1e7 /应用程序ID-905ceb2e-8bde-48ca-bcbd-937b0ed30e67

如博客文章中所述,我在“应用程序注册”中添加了应用程序角色。只是为了尝试,我从他的帖子中粘贴了完整的代码块,以查看是否可以正常工作。

{
  "appRoles": [
    {
      "allowedMemberTypes": [
        "Application"
      ],
      "displayName": "Read all things",
      "id": "32028ccd-3212-4f39-3212-beabd6787d81",
      "isEnabled": true,
      "description": "Allow the application to read all things as itself.",
      "value": "Things.Read.All"
    }
  ]
}

然后,通过运行以下脚本,我为此角色向MSI添加了新的角色分配。

New-AzureADServiceAppRoleAssignment `
    -ObjectId bf00c7e8-b14b-4fe5-b768-da255026ff17 `
    -Id 32028ccd-3212-4f39-3212-beabd6787d81 `
    -PrincipalId bf00c7e8-b14b-4fe5-b768-da255026ff17 `
    -ResourceId 9863b99a-6f28-4053-8a47-050f2b6da1e7

为了从我的 MainWebApp 获取访问令牌,我运行了以下代码。

var azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("905ceb2e-8bde-48ca-bcbd-937b0ed30e67", "b1f8cb55-7d7a-4e8d-9641-51372b423357");
// And I also tried the following
var azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://[mine].onmicrosoft.com/6c14b806-7fec-4423-88e9-ce535e07787a");

这两种方法都会产生有效的JWT,对于愚蠢的样本来说,它们看起来很熟悉。

{
  "aud": "905ceb2e-8bde-48ca-bcbd-937b0ed30e67",
  "iss": "https://sts.windows.net/b1f8cb55-7d7a-4e8d-9641-51372b423357/",
  "iat": 1574427342,
  "nbf": 1574427342,
  "exp": 1574456442,
  "aio": "42VgYHjp+2hqNdcyiVLGhlfLNFomAAA=",
  "appid": "a4e07406-b556-4c4d-9525-5f410fd21fe7",
  "appidacr": "2",
  "idp": "https://sts.windows.net/b1f8cb55-7d7a-4e8d-9641-51372b423357/",
  "oid": "bf00c7e8-b14b-4fe5-b768-da255026ff17",
  "roles": [
    "Things.Read.All"
  ],
  "sub": "bf00c7e8-b14b-4fe5-b768-da255026ff17",
  "tid": "b1f8cb55-7d7a-4e8d-9641-51372b423357",
  "uti": "FrqIC0box0imFrEVC1ZHAA",
  "ver": "1.0"
}

但是,在调用API时,我收到一个页面,提示Sign in to your account。 调用API的代码

_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await _httpClient.GetAsync("https://myaadauthapi.azurewebsites.net/api/data");

API控制器中的方法如下所示

[Authorize(Roles = "Things.Read.All")] //<-- Tried this one first, but didn't work
// [Authorize] // <-- Fallen back to this one, but didn't work either.
public IEnumerable<string> Get()
{
    return new[]
    {
        "One",
        "Een",
        "1",
        "Uno"
    };
}

当调用分配了[AllowAnonymous]属性的端点时,会从该端点得到预期的结果。

我的猜测是,我在API中的配置不正确(或Azure中的某些错误)。

// The additions I did in the ConfigureServices method in Startup class
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
    .AddAzureAD(options =>
    {
        Configuration.Bind("AzureAd", options);
    });

// And of course the addition to the Configure method
app.UseAuthentication();

当然还有应用程序设置

"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "CallbackPath": "/signin-oidc",
  "Domain": "[mine].onmicrosoft.com",
  "TenantId": "b1f8cb55-7d7a-4e8d-9641-51372b423357",
  "ClientId": "905ceb2e-8bde-48ca-bcbd-937b0ed30e67"
},

出于良好的考虑,我还添加了 MainWebApp 作为 AadAuthenticationApiOne 的所有者。 MainWebApp assigned as Owner to AadAuthenticationApiOne - Access Control

1 个答案:

答案 0 :(得分:2)

似乎您已使用API​​上的OpenID Connect配置了Azure AD身份验证。这不是正确的方法。应该使用Azure AD承载令牌身份验证配置API。它不重定向请求,它需要访问令牌。我也有关于该设置的文章;)

https://joonasw.net/view/azure-ad-authentication-aspnet-core-api-part-1