Azure Application Insights - 使用基本身份验证进行可用性测试?
Azure Application Insights - availability testing with basic auth?
我正在尝试在需要基本身份验证的端点上使用 Azure Application Insights 设置可用性测试(URL Ping 测试)。似乎标准方法与
https://username:password@myendpoint.com
未被 Azure 接受(错误消息显示 URL 格式错误,可能我在开头缺少 https/http)。
假设我想留在 Azure 生态系统中,除了使用多步 Web 测试或 Azure Functions 之外,还有其他方法可以实现此目的吗? :)
在 URL 中传递基本身份验证凭据已被 RFC 3986 弃用(这是 RFC 中的一个片段)
3.2.1. User Information
The userinfo subcomponent may consist of a user name and,
optionally, scheme-specific information about how to gain
authorization to access the resource. The user information, if
present, is followed by a commercial at-sign ("@") that delimits it
from the host.
userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
Use of the format "user:password" in the userinfo field is deprecated.
替代方法是使用 授权 header 来传递凭据。这是 Wikipedia (Basic Auth) 中关于如何构建 header 的片段。
The Authorization field is constructed as follows:[6]
- The username and password are combined with a single colon. (:)
- The resulting string is encoded into an octet sequence.[7]
- The resulting string is encoded using a variant of Base64.[8]
- The authorization method and a space is then prepended to the encoded string, separated with a space (e.g. "Basic ").
For example, if the browser uses Aladdin as the username and OpenSesame as the password, then the field's value is the base64-encoding of Aladdin:OpenSesame, or QWxhZGRpbjpPcGVuU2VzYW1l
. Then the Authorization header will appear as:
Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
您可以在 Visual Studio Enterprise 中创建一个 Web 测试 文件,然后将其上传到 Application insights 并使用它。请参阅此文档:https://docs.microsoft.com/en-us/azure/application-insights/app-insights-monitor-web-app-availability
- 在Visual StudioEnterprise中,您可以创建一个WebTest项目。
- 右键单击您的项目名称并select 添加请求。
- 现在右键单击 link 和 select 添加 Header。
- 您可以根据需要添加 header。
- 当您查看 .webtest 文件时,您会看到 Headers 部分附加在 Requests 下。
<Request>
<Headers>
<Header Name="Authorization" Value="Basic QWxhZGRpbjpPcGVuU2VzYW1l" />
</Headers>
</Request>
Ping 测试应该相对简单,目前有几种方法可以防止此类 url 匿名访问,例如策略或操作过滤器。
基于策略的授权
让我们创建一个简单的策略,它需要查询字符串中的密钥。
首先,使用处理程序创建需求,例如:
public class HasSecretKeyRequirement : IAuthorizationRequirement
{
}
public class HasSecretKeyRequirementHandler : AuthorizationHandler<HasSecretKeyRequirement>
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IConfiguration _configuration;
public HasSecretKeyRequirementHandler(IHttpContextAccessor httpContextAccessor, IConfiguration configuration)
{
_httpContextAccessor = httpContextAccessor;
_configuration = configuration;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasApiKeyRequirement requirement)
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null)
{
context.Fail();
return Task.CompletedTask;
}
if (httpContext.Request.Query.TryGetValue("SecretKey", out extractedSecretKey))
{
var secretKey= _configuration.GetValue<string>("SecretKey");
if (secretKey.Equals(extractedSecretKey))
{
context.Succeed(requirement);
return Task.CompletedTask;
}
}
httpContext.Response.ContentType = "text/plain";
httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
context.Fail();
return Task.CompletedTask;
}
}
然后使用需求创建新策略并注册需求处理程序:
services.AddAuthorization(options =>
{
options.AddPolicy("HasSecretKey", policy =>
policy.Requirements.Add(new HasSecretKeyRequirement()));
);
services.AddSingleton<IAuthorizationHandler, HasSecretKeyRequirementHandler>();
将策略应用于您的 ping 端点:
[Authorize(Policy = "HasSecretKey")]
[HttpGet("api/ping")]
public IActionResult Ping()
{
return Ok();
}
Finalldd 配置您的可用性测试:
https://yourapi.com/api/ping?SecretKey=yoursecretkey
这只是一个示例,您可以创建自己的需求和处理逻辑。您可以在您的应用程序中重用这些策略,例如在健康检查端点中:
endpoints.MapHealthChecks("/health")
.RequireAuthorization("HasSecretKey");
这种形式的授权在这种简单的情况下可能就足够了,但绝对不应该在更高级的场景中使用。
供参考:根据上面@kaushal 的回答中的片段,我能够扩展基本 URL Ping 测试 :) 我在 Terraform but you can also submit this via the REST API 中使用 XML直接地。在我的例子中,我需要添加一个任意的 header
<WebTest Name="appinsights-webtest" Id="ABD48585-0831-40CB-9069-682EA6BB3583" Enabled="True" CssProjectStructure="" CssIteration="" Timeout="30" WorkItemIds="" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" Description="" CredentialUserName="" CredentialPassword="" PreAuthenticate="True" Proxy="default" StopOnError="False" RecordedResultFile="" ResultsLocale="">
<Items>
<Request Method="GET" Guid="a5f10126-e4cd-570d-961c-cea43999a200" Version="1.1" Url="https://example.com/health/stamp" ThinkTime="0" Timeout="30" ParseDependentRequests="False" FollowRedirects="False" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8" ExpectedHttpStatusCode="200" ExpectedResponseUrl="" ReportingName="" IgnoreHttpStatusCode="False">
<Headers>
<Header Name="X-Azure-FDID" Value="xxxxxxxxxxxx-xxxxxxxx-xxx" />
</Headers>
</Request>
</Items>
</WebTest>
我没有在任何地方找到这个文档,但对我来说工作正常。
我正在尝试在需要基本身份验证的端点上使用 Azure Application Insights 设置可用性测试(URL Ping 测试)。似乎标准方法与
https://username:password@myendpoint.com
未被 Azure 接受(错误消息显示 URL 格式错误,可能我在开头缺少 https/http)。
假设我想留在 Azure 生态系统中,除了使用多步 Web 测试或 Azure Functions 之外,还有其他方法可以实现此目的吗? :)
在 URL 中传递基本身份验证凭据已被 RFC 3986 弃用(这是 RFC 中的一个片段)
3.2.1. User Information
The userinfo subcomponent may consist of a user name and, optionally, scheme-specific information about how to gain authorization to access the resource. The user information, if present, is followed by a commercial at-sign ("@") that delimits it from the host.
userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
Use of the format "user:password" in the userinfo field is deprecated.
替代方法是使用 授权 header 来传递凭据。这是 Wikipedia (Basic Auth) 中关于如何构建 header 的片段。
The Authorization field is constructed as follows:[6]
- The username and password are combined with a single colon. (:)
- The resulting string is encoded into an octet sequence.[7]
- The resulting string is encoded using a variant of Base64.[8]
- The authorization method and a space is then prepended to the encoded string, separated with a space (e.g. "Basic ").
For example, if the browser uses Aladdin as the username and OpenSesame as the password, then the field's value is the base64-encoding of Aladdin:OpenSesame, or
QWxhZGRpbjpPcGVuU2VzYW1l
. Then the Authorization header will appear as:Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
您可以在 Visual Studio Enterprise 中创建一个 Web 测试 文件,然后将其上传到 Application insights 并使用它。请参阅此文档:https://docs.microsoft.com/en-us/azure/application-insights/app-insights-monitor-web-app-availability
- 在Visual StudioEnterprise中,您可以创建一个WebTest项目。
- 右键单击您的项目名称并select 添加请求。
- 现在右键单击 link 和 select 添加 Header。
- 您可以根据需要添加 header。
- 当您查看 .webtest 文件时,您会看到 Headers 部分附加在 Requests 下。
<Request> <Headers> <Header Name="Authorization" Value="Basic QWxhZGRpbjpPcGVuU2VzYW1l" /> </Headers> </Request>
Ping 测试应该相对简单,目前有几种方法可以防止此类 url 匿名访问,例如策略或操作过滤器。
基于策略的授权
让我们创建一个简单的策略,它需要查询字符串中的密钥。
首先,使用处理程序创建需求,例如:
public class HasSecretKeyRequirement : IAuthorizationRequirement
{
}
public class HasSecretKeyRequirementHandler : AuthorizationHandler<HasSecretKeyRequirement>
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IConfiguration _configuration;
public HasSecretKeyRequirementHandler(IHttpContextAccessor httpContextAccessor, IConfiguration configuration)
{
_httpContextAccessor = httpContextAccessor;
_configuration = configuration;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasApiKeyRequirement requirement)
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null)
{
context.Fail();
return Task.CompletedTask;
}
if (httpContext.Request.Query.TryGetValue("SecretKey", out extractedSecretKey))
{
var secretKey= _configuration.GetValue<string>("SecretKey");
if (secretKey.Equals(extractedSecretKey))
{
context.Succeed(requirement);
return Task.CompletedTask;
}
}
httpContext.Response.ContentType = "text/plain";
httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
context.Fail();
return Task.CompletedTask;
}
}
然后使用需求创建新策略并注册需求处理程序:
services.AddAuthorization(options =>
{
options.AddPolicy("HasSecretKey", policy =>
policy.Requirements.Add(new HasSecretKeyRequirement()));
);
services.AddSingleton<IAuthorizationHandler, HasSecretKeyRequirementHandler>();
将策略应用于您的 ping 端点:
[Authorize(Policy = "HasSecretKey")]
[HttpGet("api/ping")]
public IActionResult Ping()
{
return Ok();
}
Finalldd 配置您的可用性测试:
https://yourapi.com/api/ping?SecretKey=yoursecretkey
这只是一个示例,您可以创建自己的需求和处理逻辑。您可以在您的应用程序中重用这些策略,例如在健康检查端点中:
endpoints.MapHealthChecks("/health")
.RequireAuthorization("HasSecretKey");
这种形式的授权在这种简单的情况下可能就足够了,但绝对不应该在更高级的场景中使用。
供参考:根据上面@kaushal 的回答中的片段,我能够扩展基本 URL Ping 测试 :) 我在 Terraform but you can also submit this via the REST API 中使用 XML直接地。在我的例子中,我需要添加一个任意的 header
<WebTest Name="appinsights-webtest" Id="ABD48585-0831-40CB-9069-682EA6BB3583" Enabled="True" CssProjectStructure="" CssIteration="" Timeout="30" WorkItemIds="" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" Description="" CredentialUserName="" CredentialPassword="" PreAuthenticate="True" Proxy="default" StopOnError="False" RecordedResultFile="" ResultsLocale="">
<Items>
<Request Method="GET" Guid="a5f10126-e4cd-570d-961c-cea43999a200" Version="1.1" Url="https://example.com/health/stamp" ThinkTime="0" Timeout="30" ParseDependentRequests="False" FollowRedirects="False" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8" ExpectedHttpStatusCode="200" ExpectedResponseUrl="" ReportingName="" IgnoreHttpStatusCode="False">
<Headers>
<Header Name="X-Azure-FDID" Value="xxxxxxxxxxxx-xxxxxxxx-xxx" />
</Headers>
</Request>
</Items>
</WebTest>
我没有在任何地方找到这个文档,但对我来说工作正常。