gpt4 book ai didi

c# - 如何告诉 [Authorize] 属性将基本身份验证与自定义消息处理程序一起使用?

转载 作者:太空宇宙 更新时间:2023-11-03 21:47:59 25 4
gpt4 key购买 nike

我正在阅读 Badri L. 在 Pro ASP .NET Web API Security 中的第 8 章,尝试为将由 HTTP/JS 客户端使用的 Web 应用程序实现基本身份验证。

我已将以下身份验证处理程序添加到我的 WebAPI 项目中:

public class AuthenticationHandler : DelegatingHandler
{
private const string SCHEME = "Basic";
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
System.Threading.CancellationToken
cancellationToken)
{
try
{
// Request Processing
var headers = request.Headers;
if (headers.Authorization != null && SCHEME.Equals(headers.Authorization.Scheme))
{
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
// etc

当我使用 [Authorize] 修饰 API 中的方法并在上面的 if 语句处设置断点时,headers.Authorization 在第一次请求时为 null。如果我继续这个休息,if 语句再次被击中,这次 headers.Authorization.Scheme 作为“Negotiate”,而不是“Basic”:

enter image description here

我已经在 WebApiConfig 中注册了我的处理程序:

config.MessageHandlers.Add(new AuthenticationHandler());

但我不知道为什么 Authorize 属性不遵守基本身份验证,或者为什么 - 因为该方案不是“基本”并且我的处理程序中的 if() 返回 false - 当我应该得到 401 Unauthorized 时,我正在从我的 API Controller 获取数据。

我没有在我的 web.config 中指定任何 authenticationType。

知道我做错了什么吗?

编辑:完整处理程序:

public class AuthenticationHandler : DelegatingHandler
{
private const string SCHEME = "Basic";
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
System.Threading.CancellationToken
cancellationToken)
{
try
{
// Request Processing
var headers = request.Headers;
if (headers.Authorization != null && SCHEME.Equals(headers.Authorization.Scheme))
{
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string credentials = encoding.GetString(Convert.FromBase64String(headers.Authorization.Parameter));
string[] parts = credentials.Split(':');
string userId = parts[0].Trim();
string password = parts[1].Trim();
// TODO: Authentication of userId and Pasword against credentials store here
if (true)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, userId),
new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Password)
};
var principal = new ClaimsPrincipal(new[] {new ClaimsIdentity(claims, SCHEME)});
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
HttpContext.Current.User = principal;
}

}

var response = await base.SendAsync(request, cancellationToken);
// Response processing
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue(SCHEME));
}
return response;
}
catch (Exception)
{
// Error processing
var response = request.CreateResponse(HttpStatusCode.Unauthorized);
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue(SCHEME));
return response;
}
}

}

最佳答案

When I decorate methods in my API with [Authorize] and set a breakpoint at the if statement above, headers.Authorization is null upon the first request.

这是预料之中的。这就是它应该如何工作的。浏览器仅在收到 401 时才会显示弹出窗口以从用户那里获取凭据。后续请求将在基本方案中包含带有凭据的授权 header 。

If I continue on this break, the if statement gets hit again, this time with headers.Authorization.Scheme as "Negotiate", instead of "Basic":

是的,正如 Dominick 的回答(是 Dominick 吗?),您启用了 Windows 身份验证,这就是您从浏览器取回协商方案的原因。您必须在配置中或使用 IIS 管理器禁用所有身份验证方法。

But I'm at a loss as to why the Authorize attribute is not respecting basic authentication, or why - since the scheme is not "basic" and the if() in my handler returns false - I'm getting data from my API controller when I should be getting 401 Unauthorized.

Authorize 属性对基本身份验证一无所知。它只关心身份是否经过验证。由于您启用了匿名身份验证(我猜是这种情况),授权属性很高兴,消息处理程序响应处理部分没有 401 来添加 WWW-Authenticate 响应 header ,指示 Web API 需要 Basic 方案中的凭据。

关于c# - 如何告诉 [Authorize] 属性将基本身份验证与自定义消息处理程序一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15961875/

25 4 0
文章推荐: html - 使用 Bootstrap 对齐输入框下的标签
文章推荐: javascript - 使用 JS/CSS 将 转换为具有完全相同位置和形状的
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com