从 Azure 函数安全地调用 Web Api
Calling WebApi from Azure function securely
我有一个场景,其中我有 asp.net 核心网络 api 和一个 azure 函数。我每 1 小时从 azure time 触发函数调用 web api。我没有在 Web api 上启用身份验证,我不想 public 访问它。只有我的 azure 函数应该能够访问网络 api。我如何限制 web api 从 public 访问,但只能从 azure 函数访问而不实施身份验证。
我尝试了以下,
在 webapi appsettings 文件中,我更新了“AllowedHosts”:“https://testfuntionapp.azurewebsites.net”。通过此更改,我的 testfuntionapp 无法访问网络 api。
我正在尝试一种具有成本效益的解决方案。
请检查我的发现是否有助于:
How can I restrict web api to access from public but only from azure function without implementing authentication.
这就是 Azure Virtual Networks 的来源。
创建虚拟网络,将 Azure 函数配置为只能在此 VNet 上调用,还可以配置核心应用程序对 VNet 的访问。
- 通过使用专用端点,只能通过您的虚拟网络访问资源。
- 如果启用虚拟网络集成,则 Azure Functions 可以通过配置的专用端点访问指定资源,这是更高级别的安全性。
参考文献:
我还建议按照 HariKrishnaRajoli 的建议使用专用端点。
理论上,仅配置 http header filtering for access restriction rules 并且只允许包含只有您的 azure 函数代码知道的秘密 header 的请求也足够了。这可能与“基本”HTTP 身份验证安全性相当,并且比其他选项弱。
作为替代方案,您可以使用 AAD 身份验证而无需真正“实施”很多身份验证代码。
- 在WebApi
上配置Easy Auth
- 为您的 Azure 函数配置 ManagedIdentity
- 使用“App Role Assignments”授予您的托管身份访问权限以调用 WebApi“
- 将您的 Azure 函数扩展到 acquire 并在调用 WebApi 时传递访问令牌
如果您只希望 Azure 函数能够访问您的网站 API,您可以通过 IP 地址限制对您网站的访问 API。
在您的网站 API 的 appsettings.json 文件中,添加以下内容:
"AllowedHosts": "https://testfuntionapp.azurewebsites.net"
这将限制对您的网站的访问 API 只有来自指定 Azure 功能的请求。
执行此操作的最快和“最肮脏”的方法是将 API 键作为 header 从函数传递给您的 REST API。
您可以将 API 键硬编码到您的配置文件或从您的数据库加载它。
我的实现:
namespace CoreApi.Middleware
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class RequirePartnerApiKeyAttribute : Attribute, IAsyncActionFilter
{
private const string ApiKeyHeaderName = "x-partner-apikey";
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
//----------------------------------------------------
// Validate Api Key
//----------------------------------------------------
if (!context.HttpContext.Request.Headers.TryGetValue(ApiKeyHeaderName, out var apiKey) ||
string.IsNullOrEmpty(apiKey))
{
context.Result = new UnauthorizedResult();
return;
}
var partnerService = context.HttpContext.RequestServices.GetRequiredService<IPartnerService>();
var apiRequest = new PartnerAuthenticateRequest { PartnerApiKey = apiKey };
var partner = partnerService.Authenticate(apiRequest, new CancellationToken()).Result;
if (partner == null)
{
context.Result = new UnauthorizedResult();
return;
}
else
{
if (Enum.IsDefined(typeof(ApiKeyTypes), partner.PartnerName))
context.HttpContext.Items["APIKeyName"] = Enum.Parse(typeof(ApiKeyTypes), partner.PartnerName);
}
//----------------------------------------------------
await next();
}
}
}
您可以通过调用以下任何中间件访问 API 密钥:context.HttpContext.Items["APIKeyName"]
我有一个场景,其中我有 asp.net 核心网络 api 和一个 azure 函数。我每 1 小时从 azure time 触发函数调用 web api。我没有在 Web api 上启用身份验证,我不想 public 访问它。只有我的 azure 函数应该能够访问网络 api。我如何限制 web api 从 public 访问,但只能从 azure 函数访问而不实施身份验证。
我尝试了以下, 在 webapi appsettings 文件中,我更新了“AllowedHosts”:“https://testfuntionapp.azurewebsites.net”。通过此更改,我的 testfuntionapp 无法访问网络 api。
我正在尝试一种具有成本效益的解决方案。
请检查我的发现是否有助于:
How can I restrict web api to access from public but only from azure function without implementing authentication.
这就是 Azure Virtual Networks 的来源。
创建虚拟网络,将 Azure 函数配置为只能在此 VNet 上调用,还可以配置核心应用程序对 VNet 的访问。
- 通过使用专用端点,只能通过您的虚拟网络访问资源。
- 如果启用虚拟网络集成,则 Azure Functions 可以通过配置的专用端点访问指定资源,这是更高级别的安全性。
参考文献:
我还建议按照 HariKrishnaRajoli 的建议使用专用端点。
理论上,仅配置 http header filtering for access restriction rules 并且只允许包含只有您的 azure 函数代码知道的秘密 header 的请求也足够了。这可能与“基本”HTTP 身份验证安全性相当,并且比其他选项弱。
作为替代方案,您可以使用 AAD 身份验证而无需真正“实施”很多身份验证代码。
- 在WebApi 上配置Easy Auth
- 为您的 Azure 函数配置 ManagedIdentity
- 使用“App Role Assignments”授予您的托管身份访问权限以调用 WebApi“
- 将您的 Azure 函数扩展到 acquire 并在调用 WebApi 时传递访问令牌
如果您只希望 Azure 函数能够访问您的网站 API,您可以通过 IP 地址限制对您网站的访问 API。
在您的网站 API 的 appsettings.json 文件中,添加以下内容:
"AllowedHosts": "https://testfuntionapp.azurewebsites.net"
这将限制对您的网站的访问 API 只有来自指定 Azure 功能的请求。
执行此操作的最快和“最肮脏”的方法是将 API 键作为 header 从函数传递给您的 REST API。
您可以将 API 键硬编码到您的配置文件或从您的数据库加载它。
我的实现:
namespace CoreApi.Middleware
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class RequirePartnerApiKeyAttribute : Attribute, IAsyncActionFilter
{
private const string ApiKeyHeaderName = "x-partner-apikey";
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
//----------------------------------------------------
// Validate Api Key
//----------------------------------------------------
if (!context.HttpContext.Request.Headers.TryGetValue(ApiKeyHeaderName, out var apiKey) ||
string.IsNullOrEmpty(apiKey))
{
context.Result = new UnauthorizedResult();
return;
}
var partnerService = context.HttpContext.RequestServices.GetRequiredService<IPartnerService>();
var apiRequest = new PartnerAuthenticateRequest { PartnerApiKey = apiKey };
var partner = partnerService.Authenticate(apiRequest, new CancellationToken()).Result;
if (partner == null)
{
context.Result = new UnauthorizedResult();
return;
}
else
{
if (Enum.IsDefined(typeof(ApiKeyTypes), partner.PartnerName))
context.HttpContext.Items["APIKeyName"] = Enum.Parse(typeof(ApiKeyTypes), partner.PartnerName);
}
//----------------------------------------------------
await next();
}
}
}
您可以通过调用以下任何中间件访问 API 密钥:context.HttpContext.Items["APIKeyName"]