在ChallengeAsync方法的上下文中身份验证设置过滤器的结果 [英] Setting Result in the context of ChallengeAsync method in an authentication filter
问题描述
此问题是关系到我这里提供答案。 OP的评论让我思考了一下。我建议使用实现类 IHttpActionResult
这样的验证过滤器的 ChallengeAsync
方法。
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
是这样的。
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
A类,但,这是正确的方式?我得到一种不安的感觉,这是某种不好的从性能的角度来看,因为这感觉就像我变换动作结果的Htt presponseMessage和回作用的结果。就需要在这里单独的类实施 IHttpActionResult
像什么,我建议将AP preciated作为对使用上述code的指针。
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.$c$cplex.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被更新,而不是返回,可以由每个呼叫者往上堆栈进行更换的Htt presponseMessage)。如果你有一个MVC实现您的身份验证过滤器,你很可能最终会做第一种方法反正。
- 稍微改变了从什么打算管道的行为。在ChallengeAsync的code的运行速度比在context.Result的code,它返回更早。例如,如果code更改的属性上的Htt prequestMessage并影响以后的过滤器的ChallengeAsync逻辑,行为可能会比什么预想的不同。
绝对框架可以更容易地实现该接口;随意在此工作项表决:
的https://aspnetwebstack.$c$cplex.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方法的上下文中身份验证设置过滤器的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!