【问题标题】:Custom Authorize for both action and api calls?为操作和 api 调用自定义授权?
【发布时间】:2013-02-15 03:51:22
【问题描述】:

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

但现在我在 api 调用方面遇到了另一面墙。我还需要以与操作调用相同的方式授权这些调用。我了解 System.Web.Http 和 System.Web.Mvc Authorize 属性之间存在差异。所以我创建了一个单独的 Api 特定属性,它基本上做同样的事情。但是,我无法像在原始属性中那样设置用户 - 主体和身份。

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

这就是我存储信息的方式

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 属性,如何轻松存储信息以供以后在控制器中使用。或者基本上我不能以这种方式为这些调用实际获取/设置身份吗?

编辑#1

我找到了如何从我的 ApiController 正确访问我的 cookie 值,我只是缺少对 System.Web >_

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      你只能从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
          }
      }
      }
      

      【讨论】:

      • 我看到您设置了 System.Threading.Thread.CurrentPrincipal... 这与 HttpContext.Current.User 有何不同?
      • 我没有仔细研究过,我发现api控制器的User对象与httpcontext.user不同,所以我推入了线程主体,它似乎可以工作。
      猜你喜欢
      • 2020-04-11
      • 2019-03-04
      • 2017-08-22
      • 1970-01-01
      • 2018-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多