我是否必须在ApplyResponseChallengeAsync中检查响应状态?

时间:2014-03-26 11:15:51

标签: c# authentication owin

我已经编写了一个相当基本的AuthenticationHandler<T>派生类,用于为我的REST服务执行自定义身份验证。

我曾假设(是的,我知道,糟糕的主意)只有在我真正需要应用我的挑战时才会调用ApplyResponseChallengeAsync - 例如它被描述为:

  

如果相关的身份验证方案将身份验证交互作为其请求流的一部分进行处理,则将此方法重写为具有401质询问题的dela( sic )。 (例如添加响应标头,或将401结果更改为登录页面或外部登录位置的302.)

对我来说,只有在发出401时才会调用它。但是,在某些有限的测试中,我们会看到以下一些例外情况:

System.Web.HttpException (0x80004005): Server cannot append header after HTTP headers have been sent.
at System.Web.HttpHeaderCollection.SetHeader(String name, String value, Boolean replace)
at Microsoft.Owin.Host.SystemWeb.CallHeaders.AspNetResponseHeaders.Set(String key, String[] values)
at Microsoft.Owin.Infrastructure.OwinHelpers.AppendHeader(IDictionary`2 headers, String key, String values)
at OurAuthHandler.ApplyResponseChallengeAsync()
at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseCoreAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<TeardownAsync>d__5.MoveNext()
--- And so on

因此,想要对此进行调查,我稍微更改了方法中的代码,以便我可以使用调试器来检查发生此异常的情况:

protected override Task ApplyResponseChallengeAsync()
{
    try
    {
        foreach (var uri in Options.IdentityConfiguration.AudienceRestriction.AllowedAudienceUris)
        {
            Response.Headers.Append("WWW-Authenticate", "Bearer realm=\"" + uri + "\"");
        }
        return base.ApplyResponseChallengeAsync();
    }
    catch
    {
        throw; //Set a breakpoint here
    }
}

而且,瞧,当我的断点被击中时,我发现Response的状态代码是200 / OK。

问题

所以,问题是,我的意思是我必须自己检查状态代码,是否有一些标志我必须传递/设置在某处,以便此方法仅调用401s,或者我错过了其他什么?< / p>

1 个答案:

答案 0 :(得分:4)

是的,您必须自己检查状态代码。该文件具有误导性。

请注意Katana project中的每个AuthenticationHandler如何检查状态代码:

public class OpenIdConnectAuthenticationHandler : AuthenticationHandler<OpenIdConnectAuthenticationOptions>
{
    ...
    protected override async Task ApplyResponseChallengeAsync()
    {
        if (Response.StatusCode == 401)
        {
            ....
        }
    }
    ...
}

internal class TwitterAuthenticationHandler : AuthenticationHandler<TwitterAuthenticationOptions>
{
    ...
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "MemoryStream.Dispose is idempotent")]
    protected override async Task ApplyResponseChallengeAsync()
    {
        if (Response.StatusCode != 401)
        {
            return;
        }
    }
    ...
}

public class WsFederationAuthenticationHandler : AuthenticationHandler<WsFederationAuthenticationOptions>
{
    ...
    protected override async Task ApplyResponseChallengeAsync()
    {
        if (Response.StatusCode == 401)
        {
            ...
        }
    }
    ...
}

我还检查了Katana项目的源代码:没有办法通过标志或其他东西来改变这种行为。