ASP.Net Web API 2授权时的不同内容

时间:2014-10-30 17:15:19

标签: asp.net asp.net-web-api oauth-2.0 owin

我有一个使用ASP.Net Web API 2的项目,并通过OWIN oAuth 2提供商提供oAuth支持。一切正常,但在尝试区分经过身份验证的用户和匿名用户时遇到了问题。

我可以很容易地提供[Authorize]和[AllowAnonymous]属性,但是我不想做我想做的事情。 [授权]只允许授权用户,[AllowAnonymous]允许任何人,无论是否经过身份验证。

我正在寻找的行为如下:

  • 用户在请求中请求端点无授权标头 - 返回端点内容的匿名版本
  • 用户请求端点在其请求中使用有效授权标头 - 返回端点内容的登录版本
  • 用户在请求中请求端点无效的授权标头 - 服务器返回状态代码401

我可以构建一个自定义属性来执行此操作,但我想知道是否有一种方法可以本地执行此操作而无需创建自定义属性。

非常感谢您提供的任何帮助。

理查德。

更新

我提出的一个选项是创建AuthorizeAttribute的子类,如下所示:

public class SuccessfulAuthorizationOrAnonymousAttribute : AuthorizeAttribute
{
    protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if(actionContext.RequestContext.Principal.Identity.IsAuthenticated)
            return base.IsAuthorized(actionContext);
        else
        {
            if (actionContext.Request.Headers.Authorization != null)
            {
                // If there's an authorization header, but there Principal.Identity.IsAuthenticated is false, then authentication must have failed
                return false;
            }
            else
            {
                // There's no authorization header - therefore the user cannot have attempted to authenticate. A true anonymous request?
                return true;
            }

        }
    }
}

逻辑是,如果用户通过此身份验证,那么我可以让基类处理他们是否真的有权查看内容。

但是,如果它们是未经身份验证的,那么我可以检查请求中是否有Authorization标头,如果有,那么我认为我可以推断出身份验证尝试失败了。如果是这种情况,那么我可以返回他们无权访问资源。

如果没有Authorization标头,那么用户没有尝试进行身份验证(我使用的API仅支持Bearer身份验证 - 没有别的),因此我可以安全地将用户视为匿名。

从我的测试来看,这种方法看起来像我想要的那样,虽然它确实感觉像是一种黑客攻击。有没有理由不这样做,我看不到?

谢谢,

理查德。

1 个答案:

答案 0 :(得分:0)

我认为你不能在同一时间接受匿名和经过身份验证的用户的单一端点中执行此操作,我的建议是创建2个端点并将业务逻辑拉到私有方法,类似下面的内容应该适用于你

[AllowAnonymous]
[HttpPost]
[Route("ActionForAnon")]
public IHttpActionResult ActionForAnon()
{
    return DoYourLogic();
}

[Authorize]
[HttpPost]
[Route("ActionForAuth")]
public IHttpActionResult ActionForAuth()
{

    return DoYourLogic();

}

private IHttpActionResult DoYourLogic()
{
    var identity = User.Identity as ClaimsIdentity;
    if (identity.IsAuthenticated)
    {
        //Your response for authenticated user
    }
    else {
        //Your response for anonymous user
    }

    return Ok();
}