azure - 从守护程序应用程序调用 Azure 中的 ASP .NET Core API

标签 azure asp.net-core azure-active-directory azure-authentication

我对 Azure AD 和身份验证机制的经验有限。到目前为止我无法弄清楚为什么不起作用。这是场景:

我在 azure Web 应用服务中部署了一个 ASP net core 2.1 应用程序。 对于身份验证,我使用 Open ID.AddOpenIdConnect 连接并提供 client_id、secret_id 等。当用户访问我的 Web API 时,他们是重定向到 Microsoft 登录。

现在我需要向不在 Azure 中的第三方应用程序(预定的 Web 作业)公开 API。

我尝试使用 Microsoft 中的示例,只有控制台应用程序,因为我已经在 Azure 中拥有了 WebApp。 运行示例我能够获取 token ,但是当我调用 API 时,响应是 Microsoft 登录页面的 HTML。

Azure 门户上

Enterprise Application -> daemon-console -> Activity -> Service Principal sign-ins

我可以看到登录成功。

注意:为了进行测试,我在本地计算机上运行 Web 应用程序,并从控制台应用程序调用 API https://localhost:44306/api/test。

Asp .net 核心应用程序:

services.AddAuthentication(option =>
{
    option.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(option =>
{
    option.Cookie.Name = "myWebApp"; 
    option.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    option.Cookie.SameSite = SameSiteMode.None;
})
.AddOpenIdConnect(option =>
{
    option.ClientId = client_id;
    option.ClientSecret = client_secret;
    option.Authority = authority;
    option.SignedOutRedirectUri = "http://localhost:44306/";
    option.CorrelationCookie.Name = "myWebAppCorrelation"; 
    option.CorrelationCookie.SecurePolicy = CookieSecurePolicy.Always;
    option.NonceCookie.Name = "WebAppNonce";
    option.NonceCookie.SecurePolicy = CookieSecurePolicy.Always;
    option.Resource = "https://graph.windows.net";
    option.ResponseType = "id_token code";
})

控制台应用程序尝试访问 API(从 Microsoft 示例中提取的代码)

app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
    .WithClientSecret(config.ClientSecret)
    .WithAuthority(new Uri(config.Authority))
    .Build();
    
result = await app.AcquireTokenForClient(scopes).ExecuteAsync(); // ok

var httpClient = new HttpClient();
var defaultRequestHeaders = httpClient.DefaultRequestHeaders;
if (defaultRequestHeaders.Accept == null || !defaultRequestHeaders.Accept.Any(m => m.MediaType == "application/json"))
{
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
defaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

HttpResponseMessage response = await httpClient.GetAsync(webApiUrl);
if (response.IsSuccessStatusCode) // ok 
{
    string json = await response.Content.ReadAsStringAsync(); // here I'm getting the HTML to login page
    var result = JsonConvert.DeserializeObject<List<JObject>>(json);
    Console.ForegroundColor = ConsoleColor.Gray;
    processResult(result);
}

示例代码和我的场景之间的唯一区别是示例中的 Web 应用程序使用 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(Configuration) 但我无法在 Asp .Net core 2.1 中使用 .AddMicrosoftIdentityWebApi

有人知道问题可能出在哪里吗?我需要添加另一个身份验证方案吗?

最佳答案

除了cookie认证之外,您还需要支持JWT认证。所以你需要添加AddJwtBearer。您还需要扩展身份验证检查,因为您现在支持多种方案。

这就是我要做的:

// public void ConfigureServices(IServiceCollection services)
services.AddAuthentication(option =>
{
    option.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    option.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, cfg => {
    cfg.Authority = authority;
    cfg.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    {
        ValidAudience = /*see scopes of your deamon app*/
    };
})
.AddCookie(option =>
{
    // ...
})
.AddOpenIdConnect(option =>
{
    // ...
})


// public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

app.UseAuthentication();
// https://github.com/aspnet/Security/issues/1847
app.Use(async (context, next) =>
{
    if (!context.User.Identity.IsAuthenticated)
    {
        var result = await context.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
        if (result.Succeeded)
        {
            context.User = result.Principal;
        }
    }
    await next();
});
app.UseAuthorization();


关于azure - 从守护程序应用程序调用 Azure 中的 ASP .NET Core API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66879774/

相关文章:

Azure Keyvault CLI 错误 : The subscription is not registered to use namespace 'Microsoft.KeyVault'

c# - 对于 Azure Blob 存储 .NET 客户端, "Microsoft.Azure.Storage.DataMovement"和 "Azure.Storage.Blobs"之间有什么区别?

sql - Azure SQL - 将列添加到外部表上的查询时出现奇怪的错误

c# - 没有服务定位器的 CQRS 调度程序

azure - 自动将用户分配到应用程序中的特定应用程序角色

azure - 启用/禁用事件订阅

azure - 在 Service Fabric 集群上发布应用程序后 HttpContext.Session 为空

c# - 传入 XML 大小写敏感问题

azure-active-directory - ADAL.js - 使用 id_token 获取 Microsoft Graph 访问 token

azure - 通过组将 AAD 用户帐户添加到 Azure DevOps