【问题标题】:Returning Descriptive 401 Messages From Owin WebApi2从 Owin WebApi2 返回描述性 401 消息
【发布时间】:2016-02-06 15:12:50
【问题描述】:

我有一个使用 owin 运行的 asp.net 4.5 web api。每当发出未经授权的请求时,它都会返回 401,并按预期返回以下响应:

{"Message":"Authorization has been denied for this request."}

我想在此响应中添加更多详细信息(过期令牌、无效角色等)并基于此 SO post 实现自定义 [AuthorizeAttribute]。

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        var response = actionContext.Request.CreateResponse<MyError>
            (new MyError() { Description = "This is why you're unauthorized" });
        response.StatusCode = HttpStatusCode.Unauthorized;
        actionContext.Response = response;
    }
}

然后像这样在我的控制器上使用它:

[MyAuthorizeAttribute(Roles = "Foo")]
public class MyController : ApiController
{
    ...
}

按预期返回 401 和以下响应:

{"Description": "This is why you're unauthorized"}

但是,我看不到如何从传递给MyAuthorizeAttribute.HandleUnauthorizedRequest 的HttpActionContext 确定请求未经授权的原因。例如,当我在本地调试并使用过期令牌发出请求时,它会抛出 SecurityTokenExpiredException 解释 IDX10223: Lifetime validation failed. The token is expired. ValidTo: '...' Current time: '...'. 或使用无效受众它抛出 SecurityTokenInvalidAudienceException 解释 Message=IDX10214: Audience validation failed. Audiences: '...'. Did not match: validationParameters.ValidAudience: 'null' or validationParameters.ValidAudiences: '...'. 我在我的Startup.cs 甚至无法在这些异常被抛出之前捕获它们。

如何使用 owin 中间件确定请求未经授权的具体原因?

【问题讨论】:

    标签: asp.net asp.net-web-api asp.net-web-api2 owin authorize-attribute


    【解决方案1】:

    还没有弄清楚如何识别过期或无效受众等,但我最终使用它来至少根据角色返回403s。

    您可以使用上面我的问题中的示例自定义消息(“您必须具有角色 X 才能访问此操作...”)。

    public class MyAuthorizeAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            base.HandleUnauthorizedRequest(actionContext);
    
            if (actionContext.RequestContext.Principal != null && 
                actionContext.RequestContext.Principal.Identity.IsAuthenticated && 
                Roles != null)
            {
                if (!Roles.Split(',').Any(x => 
                    actionContext.RequestContext.Principal.IsInRole(x.Trim())))
                {
                    actionContext.Response.StatusCode = HttpStatusCode.Forbidden;
                }
            }
        }
    }
    

    【讨论】:

    • 嘿@Greg 有没有机会使用 OWIN 来处理这个问题?
    猜你喜欢
    • 2016-10-02
    • 2014-10-14
    • 2011-02-12
    • 2014-06-22
    • 1970-01-01
    • 2015-07-02
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多