我们有一个 ASP.NET Core 7 Web API 控制器,我们使用 Azure AD B2C 作为主要身份验证,工作正常。我们需要一个端点来进行基本身份验证。我尝试创建一个自定义授权处理程序来执行此操作并且工作正常。我可以看到它正在运行并正在运行
context.Succeed
但我仍然从我的电话中收到 401 响应。就好像它正在执行 Azure AD B2C 检查但失败了。
我尝试将
[AllowAnonymous]
属性以及 [Authorize(Policy = "BasicAuth")]
放在端点上,但随后未应用任何身份验证。
public class BasicAuthHandler : AuthorizationHandler<BasicAuthRequirement>
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly AppSettings _settings;
public BasicAuthHandler(IHttpContextAccessor httpContextAccessor, IOptions<AppSettings> settings)
{
_httpContextAccessor = httpContextAccessor;
_settings = settings.Value;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, BasicAuthRequirement requirement)
{
if (ValidateBasicAuth(_httpContextAccessor.HttpContext))
{
context.Succeed(requirement);
}
else
{
var response = _httpContextAccessor.HttpContext.Response;
response.Clear();
response.StatusCode = 401;
context.Fail();
}
return Task.CompletedTask;
}
private bool ValidateBasicAuth(HttpContext context)
{
string authHeader = context.Request.Headers["Authorization"];
if (authHeader != null && authHeader.StartsWith("Basic"))
{
string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));
int seperatorIndex = usernamePassword.IndexOf(':');
var username = usernamePassword.Substring(0, seperatorIndex);
var password = usernamePassword.Substring(seperatorIndex + 1);
if (username.Equals(_settings.BasicAuth.Username, StringComparison.OrdinalIgnoreCase) && password.Equals(_settings.BasicAuth.Password))
return true;
}
return false;
}
}
如何为不同的端点设置两种不同的身份验证方法?
授权和身份验证是两个不同的术语,含义不同。
简而言之,身份验证包括识别(找出呼叫者是谁)和验证他们是否是他们所说的人。例如,在Basic身份验证示例中,UserName告诉您呼叫者是谁,而PassWord允许您验证他们是否确实是那个Identity。 另一方面,授权正在检查调用者的身份是否有权访问应用程序中的某些资源或操作。
您提到的属性
[AllowAnonymous]
和[Authorize]
适用于授权部分。
顺便说一句,如果您想使用命名授权策略,您必须首先在应用程序启动中定义它们,例如:
services.AddAuthorization(options =>
{
var policy1 = new YourAuthorizationPolicy1();
var policy2 = new YourAuthorizationPolicy2();
options.AddPolicy("PolicyName1", policy1);
options.AddPolicy("PolicyName2", policy2);
options.DefaultPolicy = policy1;
});
同样,您可以在应用程序启动中定义多个 Authentication 方案,我相信这可以回答您的问题。 在下面的示例中,应用程序将接受Basic身份验证和Bearer身份验证。
services.AddAuthentication().AddScheme<BasicAuthOptions, BasicAuthHandler>("Basic", options =>
{
})
.AddBearerToken("Bearer", options =>
{
});
请注意,您的
BasicAuthHandler
必须继承AuthenticationHandler
,而不是AuthorizationHandler
请注意,ASP.Net inf 代码将枚举所有已注册的身份验证处理程序,并为每次尝试获取调用者的Identity
授权发生在管道中,然后是身份验证,所以我建议如果您想要自定义授权策略,仅允许调用者以某种方式进行身份验证,您的身份验证处理程序可以向创建的身份添加特定声明,您可以用于授权。
希望这有帮助。