如何在.net(web api 2 + owin)中为不同的身份验证设置混合授权

时间:2014-04-21 15:28:51

标签: .net restful-authentication owin asp.net-web-api2 authorize

我是.net的新手,我正在尝试创建一个restfull服务,您可以通过OAuth2对Facebook等服务进行身份验证,并且能够使用"普通帐户"进行登录。来自VS2013的SPA模板让我可以快速轻松地完成这项工作,我很满意。

现在我面临着另一个问题。我似乎无法找到一种方法来分离这些不同类型登录的访问权限。例如,我想只允许来自oauth身份验证方法的用户访问X和以正常方式进行身份验证的用户" (也带有持票人令牌)只能看到Y.

我搜索了网页,似乎我应该使用[授权]标签,但我不确定如何自定义它,也不区分不同的登录。 我找到了不同的自定义标签的方法,但似乎都没有工作,我一直在寻找过时的解决方案。

有人可以帮忙吗?

谢谢!


我的最终解决方案(感谢0leg)

为每种身份验证类型创建一个authorize标记:

public class AuthorizeExternalsOnly : AuthorizeAttribute
{
    protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
    {

        if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
        {
            string externalClaim = "";
            try
            {
                externalClaim = (actionContext.ControllerContext.RequestContext.Principal.Identity as ClaimsIdentity).Claims.FirstOrDefault(x => x.Type == ClaimTypes.Authentication).Value;
            }
            catch (NullReferenceException)
            {
                Debug.WriteLine("no external claim found");
            }
            if (externalClaim != "")
            {
               return base.IsAuthorized(actionContext);
            }
            return false;
        }
        return false;
    }
}

在帐户控制器上,我在 GetExternalLogin

添加了声明。
oAuthIdentity.AddClaim(new Claim(ClaimTypes.Authentication, "External"));
(...)
identity.AddClaim(new Claim(ClaimTypes.Authentication, "External"));

在每次登录之前。

1 个答案:

答案 0 :(得分:1)

您可以创建声明以定义您的用户类型(内部,Facebook等)。然后创建自定义Authorize属性以进行授权决策。

查看thisthisthis链接以获取一些背景信息。

自定义Authorize属性的代码示例。 HttpActionContext参数可让您查看您调用的控制器和操作。它还允许您检查用户的Claims集合。逐步执行不同登录方案的代码,您将拥有不同的声明。然后,您可以决定您的Controller.Action是否获得特定索赔值的授权。

protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
{
    ActionName = actionContext.ActionDescriptor.ActionName,
    ControllerName = actionContext.ControllerContext.ControllerDescriptor.ControllerName,
    Claims = (actionContext.RequestContext.Principal.Identity as ClaimsIdentity).Claims.ToList()
}