代码之家  ›  专栏  ›  技术社区  ›  Jayendran

在Web API(.Net Framework)中创建自定义属性

  •  9
  • Jayendran  · 技术社区  · 6 年前

    我正在使用OAuth2。我的WebAPI中的0 Owin(密码授予)。我最初的象征性回应如下

    {
        "access_token": "_ramSlQYasdsRTWEWew.....................",
        "token_type": "bearer",
        "expires_in": 17999,
        "permissions": {
            "user": [
                "Add",
                "Update",
                "Delete"
            ],
            "Product": [
                "Read",
                "Create"
            ]
        }
    }
    

    我已经 customized 通过创建一个名为 permissions 它们拥有相应用户的权限。

    从这里,我需要验证我的客户的每个请求 Resource server ,通过使用Authorize属性检查用户是否有足够的权限调用API。

    我发现了一个类似的例子 here 它处理的是点网核心,这不适合我的情况。

    困难的是 permission JSON密钥本身就与 ArrayList

    [CustomAuthorize(PermissionItem.Product, PermissionAction.Read)]
        public async Task<IActionResult> Index()
        {
            return View(Index);
        }
    
    public class CustomAuthorize : AuthorizeAttribute {
        public AuthorizeAttribute (PermissionItem item, PermissionAction action) {
            //Need to initalize the Permission Enums
        }
        public override void OnAuthorization (HttpActionContext actionContext) {
            //Code to get the value from Permissions ArrayList and compare it with the Enum values
        }
    }
    

    以上就是我的想法。但由于问题的复杂性 Permissions 键和枚举比较我无法前进。

    此外,还有一个问题,比如用户的权限是否为“添加”以及“更新”,这意味着我需要在控制器之前创建两个属性条件。

    喜欢

    [CustomAuthorize(PermissionItem.User, PermissionAction.Add)]
    [CustomAuthorize(PermissionItem.User, PermissionAction.Update)]
    

    这会导致添加更多的属性行。那么,有没有办法让它成为一个单一的条件 | 分开了?

    [CustomAuthorize(PermissionItem.User, PermissionAction.Update|PermissionAction.Add)]
    
    3 回复  |  直到 6 年前
        1
  •  7
  •   Dipen Shah    6 年前

    为什么不允许CustomAuthorize构造函数有多个权限操作。

    public class CustomAuthorize : AuthorizeAttribute
    {
        private readonly PermissionAction[] permissionActions;
    
        public CustomAuthorize(PermissionItem item, params PermissionAction[] permissionActions)
        {
            this.permissionActions = permissionActions;
        }
    
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            var currentIdentity = System.Threading.Thread.CurrentPrincipal.Identity;
            if (!currentIdentity.IsAuthenticated) {
                // redirect to access denied page
            }
    
            var userName = currentIdentity.Name;
            // step 1 : retrieve user object
    
            // step 2 : retrieve user permissions
    
            // step 3 : match user permission(s) agains class/method's required premissions
    
            // step 4 : continue/redirect to access denied page
        }
    }
    

    你将用以下内容为你的课堂做注解: [CustomAuthorize(PermissionItem.User, PermissionAction.Update, PermissionAction.Add)]

    我不确定OP在这里想要实现什么。如果您依赖HTTP请求来提供访问权限,那么这是一个很大的安全漏洞。在每个请求中,您应该从数据库中检索用户的访问权限信息,然后根据类/方法的所需权限进行匹配。

    CustomAttribute的实现

    public class CustomAuthorize : System.Web.Http.AuthorizeAttribute
    {
        private readonly PermissionAction[] permissionActions;
    
        public CustomAuthorize(PermissionItem item, params PermissionAction[] permissionActions)
        {
            this.permissionActions = permissionActions;
        }
    
        protected override Boolean IsAuthorized(HttpActionContext actionContext)
        {
            var currentIdentity = actionContext.RequestContext.Principal.Identity;
            if (!currentIdentity.IsAuthenticated)
                return false;
    
            var userName = currentIdentity.Name;
            using (var context = new DataContext())
            {
                var userStore = new UserStore<AppUser>(context);
                var userManager = new UserManager<AppUser>(userStore);
                var user = userManager.FindByName(userName);
    
                if (user == null)
                    return false;
    
                foreach (var role in permissionActions)
                    if (!userManager.IsInRole(user.Id, Convert.ToString(role)))
                        return false;
    
                return true;
            }
        }
    }
    
        2
  •  1
  •   3dd    6 年前

    你可以让我们使用标志和二进制操作,让你把不同的操作放在一起。

    下面的代码显示了一个如何实现的小示例

    class Program {
        static void Main(string[] args) {
            Test test = new Test();
            CustomAuthorizeAttribute customAuthorizeAttribute = (CustomAuthorizeAttribute)Attribute.GetCustomAttribute(typeof(Test), typeof(CustomAuthorizeAttribute));
    
            customAuthorizeAttribute.Test();
    
            Console.ReadKey();
        }
    }
    
    [CustomAuthorize(PermissionActions = PermissionAction.Add | PermissionAction.Delete)]
    public class Test {
    
    }
    
    public class CustomAuthorizeAttribute : Attribute {
        public PermissionAction PermissionActions { get; set; }
    
        public void Test() {
            if ((PermissionActions & PermissionAction.Add) == PermissionAction.Add) Console.WriteLine("Add");
            if ((PermissionActions & PermissionAction.Delete) == PermissionAction.Delete) Console.WriteLine("Delete");
            if ((PermissionActions & PermissionAction.Update) == PermissionAction.Update) Console.WriteLine("Update");
        }
    }
    
    public enum PermissionAction {
        Add = 1,
        Update = 2,
        Delete = 4
    }
    

    这将产生以下输出

    enter image description here

        3
  •  1
  •   Parth Akbari    6 年前

    我们已经创建了下面的API过滤器进行身份验证。

    这里,“SecretToken”、“MerchantKey”这两个密钥传递到API请求中。我们正在使用“IsValidMerchant”函数从数据库中验证这两个。

    IsValidMerchant 此函数直接连接存储相应值的数据库表

    public void OnAuthorization(AuthorizationFilterContext actionContext)
    {
      const string secretTokenName = "SecretToken";
      const string merchentKeyName = "MerchantKey";
      bool isValid = false;
    
      if (!actionContext.Filters.Any(item => item is IAllowAnonymousFilter))
        {
         CPServiceResponse response = new CPServiceResponse();
         var secretToken = actionContext.HttpContext.Request.Headers[secretTokenName].FirstOrDefault();
         var merchentKey = actionContext.HttpContext.Request.Headers[merchentKeyName].FirstOrDefault();
    
          isValid = this.IsValidMerchant(merchentKey, secretToken,_productCode);
    
           if (isValid == false)
            {
              response.Status = (int)HttpStatusCode.Unauthorized;
              response.Message = Hegic.Shared.Resource.Common.UnauthorizedRequestError;
              actionContext.Result = new JsonResult("")
                    {
                        Value = new { Status = response }
                    };
             }
          }
      }