Skip to content

用基于接口的可扩展枚举提供更多权限支持 #286

Description

@jerrylususu

APIJSON 本身的权限定义在枚举 RequestRole 中,且与框架本身的耦合度较高,如果想要在此基础上定义新的权限级别不是很方便。虽然可以通过重载 AbstractVerifier.verifyAccess 方法来自定义鉴权,但是用起来还是相对比较复杂,如(这个 issue https://github.com/Tencent/APIJSON/issues/228)。

为了尝试解决这一问题,我定义了一个新的接口 IRequestRole,令 RequestRole 实现这个接口,再依次修改框架中其他相关联的位置。通过 IRequestRole.register 方法,用户可以注册自己的权限枚举。通过 IRequestRole.get 方法,可以从权限字符串转换回对应的权限枚举。

根据我在自己的示例项目上的测试,基本可以满足需要。但是因为包含一些破坏性变更(MethodAccess 注解返回 String[]),我希望先了解下各位的意见和建议。

可以从这里获取修改后的代码(含 APIJSON ORM 和 Framework)及示例项目:
https://github.com/jerrylususu/apijson_role_extend

具体的使用方法如下:

  1. 首先定义自己的权限枚举类(可参照 apijson.demo.config.MyRole)

    public enum MyRole implements IRequestRole {
        STUDENT,
        TEACHER,
        PRINCIPAL;
    }
  2. 在 DemoApplication 的 static 块中注册自己的权限枚举类

    static {
        IRequestRole.register(MyRole.class);
        APIJSONApplication.DEFAULT_APIJSON_CREATOR = // ...
    }
  3. 在自己的用户类(model.User)中添加 List<String> role 属性,并添加对应的 getter, setter 方法

  4. 重载 AbstractVerifier.verifyAccess,补全一部分框架中未完成的鉴权逻辑(判断用户请求中声明的权限,是否的确存在于用户的权限列表中)

    此部分与用户自己的用户类的类名相关,因此没有在框架中实现(可能可以用 Visitor 接口实现?)

    // 自定义的权限,需要检查是否存在于列表中
    if ( !(config.getRole() instanceof RequestRole) ) {
        List<String> visitorRoleList = new ArrayList<>();
        // 处理数据库中 role 列为 NULL
        if (((User) this.visitor).getRole() != null) {
            visitorRoleList = ((User) this.visitor).getRole();
        }
    
        if (!visitorRoleList.contains(config.getRole().toString())){
            // 用户声明的权限不在自己的 role 列表中(伪造权限)
            throw new IllegalAccessException("当前用户没有声明的权限!");
        }
    
    }
  5. 在数据库 Access 表中完成对应配置

  • GET/GETS/HEAD/HEADS:["STUDENT", "TEACHER","PRINCIPAL"]
  • POST/DELETE:["TEACHER"]
  • PUT:["OWNER","PRINCIPAL"]
  1. 在调用时先登录,然后用 @role 声明对应的权限

    // POST /get
    {
        "[]": {
            "Course": {
                "@role": "TEACHER"
            }
        }
    }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions