基于RESTful API 权限管理

基于RESTful API 权限管理

RESTful API

REST的全称是Resource Representational State Transfer,即:资源在网络中以某种形式进行转换

  • 资源:资源是一个很宽泛的概念,它可以是文档或图像、临时服务、其他资源的集合,万物皆为资源。
  • 状态转换:数据和状态的变化。HTTP协议里面,POST、DELETE、PUT、GET增删改查,对应四种基本操作:
    • POST 用来新建资源

    • DELETE 用来删除资源

    • PUT 用来更新资源

    • GET 用来获取资源

RESTful API是目前比较成熟的的一套应用程序API设计理论。

资源分类

清楚什么是RESTful API后,接着我们将资源做个分类,不同分类做不同的鉴权策略。我将资源分为下面三大类:

20210309004549

  • 角色资源:受控资源,一个角色可以对应多个资源,角色下的用户拥有对应角色划分的资源权限。
  • 公共资源:受控资源,用户登录或持有令牌即可访问资源。
  • 开放资源:不受控资源。任何人都可以访问。

资源标记

通过我们是通过C#的特性Attribute去标记不同的资源。

  • 角色资源:没有标记特性的资源作为角色资源
  • 公共资源:自定义特性:CommonAttribute标记公共资源
  • 开放资源:利用自带特性性AllowAnonymousAttribute标记开放资源

资源管控

1.创建一张权限表Permission存储系统所有的资源。
2.创建一张角色权限表RolePermission存储角色对应的权限资源。
3.自定义一个特性PermissionValidateAttribute继承自带的认证特性AuthorizeAttribute,并实现认证过滤接口IAuthorizationFilter。在实现方法OnAuthorization中管控资源权限,实现代码大概如下:

   public class PermissionValidateAttribute : AuthorizeAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            //排除开放资源
            if (context.ActionDescriptor.EndpointMetadata.Any(m => m.GetType() == typeof(AllowAnonymousAttribute)))
                return;

            //未登录
            var loginInfo = 获取用户登录信息;
            if (loginInfo == null || string.IsNullOrEmpty(loginInfo.UserName))
            {
                context.Result = new ChallengeResult();
                return;
            }

            //排除公共管控
            if (context.ActionDescriptor.EndpointMetadata.Any(m => m.GetType() == typeof(CommonAttribute)))
                return;

            //角色资源管控
            var permission= 获取角色资源

            var httpMethod = (HttpMethod)Enum.Parse(typeof(HttpMethod), context.HttpContext.Request.Method); 
            var area = context.ActionDescriptor.RouteValues["area"];
            var controller = context.ActionDescriptor.RouteValues["controller"];
            var action = context.ActionDescriptor.RouteValues["action"];

            if (!permissions.Any(m => m.EqualsIgnoreCase($"{area}_{controller}_{action}_{httpMethod}")))
            {
                //无权访问
                context.Result = new ForbidResult();
            }
        }
    }

4.最后将自定特性PermissionValidateAttribute标记在Controller层的类或方法中即可以实现资源的权限管控。

posted @ 2021-03-25 23:46  陈曦-LR  阅读(217)  评论(0)    收藏  举报