自定义授权动作和api呼叫?

时间:2013-02-28 19:45:17

标签: asp.net-mvc asp.net-mvc-4 attributes asp.net-web-api

我最近询问this question并成功设置了自定义授权属性。

但是现在我已经打了一个关于api电话的墙。我需要以与动作调用相同的方式授权这些调用。我知道System.Web.Http和System.Web.Mvc授权属性之间存在差异。所以我创建了一个单独的Api特定属性,基本上做同样的事情。但是,我在设置User - principal和identity时遇到了问题,就像我在原始属性中那样。

我的属性只需检查cookie中的某些值以授权请求,一旦该属性读取了cookie,我将解密的cookie信息存储在自定义主体/身份设置中。在我的Api调用中,当我从身份中检索此信息时,我的强制转换失败并且我收到一个空值。

这是我存储信息的方式

阿比

HttpContext.Current.User = new MyPrinciple(new MyIdentity(decCookie.Name, decCookie.UserData));

动作

filterContext.RequestContext.HttpContext.User = new MyPrinciple(new MyIdentity(decCookie.Name, decCookie.UserData));

我如何检索我假设的所需信息

(User.principal.Identity as MyIdentity).MyData;

问题

  1. 我是否真的需要2个独立的属性
  2. 对于Api属性,如何轻松存储信息以供以后在控制器中使用。或者基本上我不能以这种方式为这些调用实际获取/设置标识吗?
  3. 编辑#1

    我发现如何从我的ApiController正确访问我的cookie值,我只是缺少对System.Web> _<的引用。问题#2已经解决了!但#1仍然存在。

2 个答案:

答案 0 :(得分:3)

Web API和MVC没有任何共同点(技术上) - 即使它们看起来相同。您需要两个单独的属性。

答案 1 :(得分:1)

您只能在c#中的一个类中继承,并且每个authorizeattribute都存在于自己的命名空间中,因此您无法在单个类中执行此操作。

您可以将其保存在公共命名空间中,然后调用公共类来进行提升。

可能的解决方案(未经测试)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace Common.Attributes
{
public class CustomAuthorize : System.Web.Mvc.AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if (!HttpContext.Current.Request.IsAuthenticated || (HttpContext.Current.User as User) != null)
            return;

        filterContext.HttpContext.User = Authorize.ExtractIdentity(filterContext.HttpContext);
    }
}

public class CustomHttpAuthorize : System.Web.Http.AuthorizeAttribute
{
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        base.OnAuthorization(actionContext);

        if (!HttpContext.Current.Request.IsAuthenticated || (HttpContext.Current.User as User) != null)
            return;

            System.Threading.Thread.CurrentPrincipal = Authorize.ExtractIdentity(filterContext.HttpContext);
        }
    }  
}

public static class Authorize
{
    public static IIdentity ExtractIdentity(HttpContext context)
    {
        // do your magic here
    }
}
}