1

我正在尝试按照这个 2013 指南设置每个请求的错误处理策略。

  • 如果请求是本地的,则显示错误信息。
  • 如果当前用户在 IT 组中,则显示错误信息。
  • 对于其他所有人,不要显示错误。

我的代码:

public class PerRequestErrorPolicyDelegatingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Properties[HttpPropertyKeys.IncludeErrorDetailKey] = new Lazy<bool>(() =>
        {
            // CHECK USER
            var identity = request.GetRequestContext().Principal as ClaimsPrincipal;
            return identity != null && identity.Identity.IsAuthenticated && identity.IsInRole("IT");
        });

        return base.SendAsync(request, cancellationToken);
    }
}

它被注册为第一个处理程序:

public static void Configure(HttpConfiguration http)
{
    http.MessageHandlers.Add(new PerRequestErrorPolicyDelegatingHandler());
    ...
}

我的 Web Api 托管在 Owin 上,但我没有看到相关的 Owin 代码,所以我省略了它。为了测试,我正在使用这个控制器:

[AllowAnonymous]
[RoutePrefix("api/sandbox")]
public class SandboxApiController : ApiController
{
    [HttpPost, Route("test")]
    public IHttpActionResult Test()
    {
        throw new InvalidOperationException($"you screwed up. Local: {RequestContext.IsLocal}, IT: {User.IsInRole("IT")}");
    }
}

在本地,我总是得到错误信息,并且延迟加载代码(由“CHECK USER”表示)永远不会执行,所以我不知道如何调试它。

部署到服务器,无论是否经过身份验证,我都不会收到任何错误信息。

我的 web.config 中没有自定义错误配置。

我做错了什么?

4

1 回答 1

0

我认为我所遵循的指南太旧而不再相关,而是采用了这种方法。它更简单,并且有效。

我们将 替换ExceptionResult为新的,在其中指定是否应包含详细信息。我们从现有结果中复制其他依赖项。

public class PerUserErrorDetailExceptionHandler : ExceptionHandler
{
    public override void Handle(ExceptionHandlerContext context)
    {
        var exResult = context.Result as ExceptionResult;
        if (!context.CatchBlock.IsTopLevel || exResult == null)
            return;

        var identity = context.RequestContext.Principal as ClaimsPrincipal;
        var showErrorDetail = identity != null
                              && identity.Identity.IsAuthenticated
                              && identity.IsInRole("IT");

        context.Result = new ExceptionResult(
            exResult.Exception,
            showErrorDetail,
            exResult.ContentNegotiator,
            exResult.Request,
            exResult.Formatters);
    }
}

在其他地方,在 Web Api 配置中:

public static void Configure(HttpConfiguration http)
{
    http.Services.Replace(typeof(IExceptionHandler), new PerUserErrorDetailExceptionHandler());
}
于 2018-04-18T19:13:37.017 回答