C# 如何在IAAuthenticationFilter实现中设置WWW身份验证标头?

C# 如何在IAAuthenticationFilter实现中设置WWW身份验证标头?,c#,asp.net-mvc,asp.net-web-api,asp.net-mvc-5,basic-authentication,C#,Asp.net Mvc,Asp.net Web Api,Asp.net Mvc 5,Basic Authentication,我正在使用MVC5的IAAuthenticationFilter接口实现基本身份验证。我的理解是,这是现在首选的方法,而不是使用授权处理程序。我已经让它工作了,但是www认证头没有在响应中返回。这是我对ChallengeAsync的实现: public async Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken) { va

我正在使用MVC5的IAAuthenticationFilter接口实现基本身份验证。我的理解是,这是现在首选的方法,而不是使用授权处理程序。我已经让它工作了,但是www认证头没有在响应中返回。这是我对ChallengeAsync的实现:

public async Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
    {
        var result = await context.Result.ExecuteAsync(cancellationToken);
        if (result.StatusCode == HttpStatusCode.Unauthorized)
        {
            result.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Basic", "realm=localhost"));
        }
    }

如果我在AuthenticateTasync中设置标题,则返回标题,但我认为应该在ChallengeAsync中设置标题。很难找到示例实现。

ChallengeAsync
中,将
上下文.Result
设置为
IHttpActionResult
类型的实例,如下所示

public Task ChallengeAsync(HttpAuthenticationChallengeContext context,
                                  CancellationToken cancellationToken)
{
    context.Result = new ResultWithChallenge(context.Result);
    return Task.FromResult(0);
}
public class ResultWithChallenge : IHttpActionResult
{
    private readonly IHttpActionResult next;

    public ResultWithChallenge(IHttpActionResult next)
    {
        this.next = next;
    }

    public async Task<HttpResponseMessage> ExecuteAsync(
                                CancellationToken cancellationToken)
    {
        var response = await next.ExecuteAsync(cancellationToken);
        if (response.StatusCode == HttpStatusCode.Unauthorized)
        {
            response.Headers.WwwAuthenticate.Add(
                   new AuthenticationHeaderValue("Basic", "realm=localhost"));
        }

        return response;
    }
}
像这样提供一个实现

public Task ChallengeAsync(HttpAuthenticationChallengeContext context,
                                  CancellationToken cancellationToken)
{
    context.Result = new ResultWithChallenge(context.Result);
    return Task.FromResult(0);
}
public class ResultWithChallenge : IHttpActionResult
{
    private readonly IHttpActionResult next;

    public ResultWithChallenge(IHttpActionResult next)
    {
        this.next = next;
    }

    public async Task<HttpResponseMessage> ExecuteAsync(
                                CancellationToken cancellationToken)
    {
        var response = await next.ExecuteAsync(cancellationToken);
        if (response.StatusCode == HttpStatusCode.Unauthorized)
        {
            response.Headers.WwwAuthenticate.Add(
                   new AuthenticationHeaderValue("Basic", "realm=localhost"));
        }

        return response;
    }
}
公共类ResultWithChallenge:IHttpActionResult
{
私有只读IHttpActionResult next;
public ResultWithChallenge(IHttpActionResult下一步)
{
this.next=next;
}
公共异步任务ExecuteAsync(
取消令牌(取消令牌)
{
var response=wait next.ExecuteAsync(cancellationToken);
if(response.StatusCode==HttpStatusCode.Unauthorized)
{
response.Headers.WwwAuthenticate.Add(
新的AuthenticationHeaderValue(“基本”、“领域=本地主机”);
}
返回响应;
}
}

谢谢!看起来他们本可以让实现变得更容易,但这个解决方案效果很好。如果你想让它更容易,请随意投票支持这个工作项:@JamieIde:请看大卫的答案-。