问题描述
这个问题与我在此处提供的答案有关.OP的评论让我思考了一下.我建议在身份验证过滤器的 ChallengeAsync
方法中使用一个实现 IHttpActionResult
的类.
This question is related to the answer I have provided here. OP's comment got me thinking a bit. I suggested using a class implementing IHttpActionResult
like this in the ChallengeAsync
method of the authentication filter.
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;
}
}
代替这个,我可以像这样简化ChallengeAsync
.
Instead of this, I can simplify the ChallengeAsync
like this.
public 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"));
}
context.Result = new ResponseMessageResult(result);
}
这使我免于创建一个实现 IHttpActionResult
的类,但这是正确的方法吗?我有一种不安的感觉,从性能的角度来看,这在某种程度上很糟糕,因为感觉就像我正在将操作结果转换为 HttpResponseMessage 并返回到操作结果.任何关于这里需要一个单独的类的指针实现 IHttpActionResult
就像我建议的那样,将不胜感激,而不是使用上面的代码.
This saves me from creating a class implementing IHttpActionResult
but is this the right way? I get an uneasy feeling that this is somehow bad from a performance standpoint because it feels like I'm converting action result to HttpResponseMessage and back to action result. Any pointers on the need for a separate class here implementing IHttpActionResult
like what I suggested will be appreciated as against using the code above.
推荐答案
目的是使用第一种方法而不是第二种方法.例如,请参阅基本身份验证示例(也可用于 MVC),它遵循第一种方法:http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/BasicAuthentication/ReadMe.txt
The intent was to use the first approach rather than the second. For example, see the Basic Authentication sample (also available for MVC), which follows the first approach:http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/BasicAuthentication/ReadMe.txt
第二种方法大多有效.我不会太在意性能的观点;无论哪种方式,您都分配了一个操作结果对象和一个响应消息对象,所以我看不出有太大区别.
The second approach mostly works. I wouldn't be too concerned about the performance standpoint; either way you're allocating one action result object and one response message object, so I'm not seeing much difference there.
但是,我推荐第一种方法有几个原因:
However, there are a couple of reasons I'd recommend the first approach:
- 第二种方法在 MVC 中的工作方式不同.MVC 和 Web API 都有身份验证过滤器,它们的工作方式基本相同.但是在 MVC 中,没有等效于 ResponseMessageResult (HttpContext 根据需要更新,而不是返回一个 HttpResponseMessage 可以由每个调用者在堆栈中进行替换).如果您有身份验证过滤器的 MVC 实现,那么无论如何您最终很可能会采用第一种方法.
- 它略微改变了管道行为,与预期不同.ChallengeAsync 中的代码早于它返回的 context.Result 中的代码运行.例如,如果代码更改了 HttpRequestMessage 上的一个属性并影响了后续过滤器的 ChallengeAsync 逻辑,则行为可能与预期不同.
该框架肯定可以使接口的实现更容易;随意对这个工作项目投票:https://aspnetwebstack.codeplex.com/workitem/1456
The framework definitely could make it easier to implement the interface; feel free to vote on this work item:https://aspnetwebstack.codeplex.com/workitem/1456
这篇关于在身份验证过滤器中的 ChallengeAsync 方法的上下文中设置结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!