从守护程序应用程序在 Azure 中调用 ASP .NET Core API
Call ASP .NET Core API in Azure from daemon application
我对 Azure AD
和身份验证机制的经验有限。到目前为止,我无法弄清楚为什么不起作用。这是场景:
我在 azure
网络应用服务中部署了一个 ASP net core 2.1
应用程序。
对于身份验证,我使用 Open ID
连接 .AddOpenIdConnect
并提供 client_id, secret_id
等。当用户访问我的网站 API 时,他们将被重定向到 Microsoft 登录。
现在我需要将 API 公开给不在 Azure
.
中的第三方应用程序(计划的 Web 作业)
我尝试使用 Microsoft 中的示例,仅使用控制台应用程序,因为我已经在 Azure
中使用了 WebApp
。
运行 我能够获取令牌的示例,但是当我调用我的 API 时,响应是 HTML Microsoft 登录页面。
在 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 AD
和身份验证机制的经验有限。到目前为止,我无法弄清楚为什么不起作用。这是场景:
我在 azure
网络应用服务中部署了一个 ASP net core 2.1
应用程序。
对于身份验证,我使用 Open ID
连接 .AddOpenIdConnect
并提供 client_id, secret_id
等。当用户访问我的网站 API 时,他们将被重定向到 Microsoft 登录。
现在我需要将 API 公开给不在 Azure
.
我尝试使用 Microsoft 中的示例,仅使用控制台应用程序,因为我已经在 Azure
中使用了 WebApp
。
运行 我能够获取令牌的示例,但是当我调用我的 API 时,响应是 HTML Microsoft 登录页面。
在 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();