Skip to content
zhōuhào edited this page Dec 13, 2017 · 10 revisions

权限控制

hsweb除了提供了基本的RDAC权限控制外,还提供了数据权限控制,并且可以灵活拓展.

默认的权限实现hsweb-authorization-basic基于aop进行控制,将会拦截所有注解Controller的类的方法

获取当前登录用户

    //第一种方式: 使用参数注入的方式获取
    @RequestMapping
    public ResponseMessage<String> getLoginUserId(Authentication auth){    
      return ok(auth.getUser().getId());
    }

   //第二种方式: 使用静态方法获取
    @RequestMapping
    public ResponseMessage<String> getLoginUserId(){
      Authentication auth=Authentication.current().orElseThrow(UnAuthorizedException::new);
      return ok(auth.getUser().getId());
    }

更多Authentication的细节,请查看源代码

使用注解声明权限控制

hsweb默认提供了使用注解来声明权限控制,可以在Controller类以及方法上进行注解,如果类和方法上同时存在注解,则将其合并.

    //第一种方式: 使用参数注入的方式获取
    @RequestMapping("/users")
    @Authorize(permission="user",action="query") //代表调用此接口时,需要拥有user的query操作的权限
    @RequiresDataAccess //声明要进行数据权限控制
    public ResponseMessage<PagerResult> queryUser(QueryParamEntity param){    
      return ok(userService.selectPager(param));
    }

注解的更多属性,请查看源代码

自定义声明权限控制

除了使用注解外,还可以通过自定义的方式,告诉hsweb哪些请求需要进行权限控制以及如何控制. 实现AopMethodAuthorizeDefinitionCustomizerParser接口,并注入给spring,在方法被拦截到时,会首先调用此接口获取AuthorizeDefinition,如果返回null或者EmptyAuthorizeDefinition则将不进行权限控制.注意: 通过AopMethodAuthorizeDefinitionCustomizerParser获取的配置将不会进行缓存,需要自行实现.

拓展数据权限控制

  1. 将数据库中的配置转为权限框架需要的配置接口

实现接口:DataAccessConfigConvert 例如:

@Component
public class MyDataAccessConfigConvert implements DataAccessConfigConvert {
    @Override
    public boolean isSupport(String type, String action, String config) {
        return "custom-access".equals(type);
    }

    @Override
    public DataAccessConfig convert(String type, String action, String config) {
        //构造配置实例
        MyDataAccessConfig myConfig = JSON.parseObject(config, MyDataAccessConfig.class);
        myConfig.setAction(action);
        myConfig.setType(type);
        return myConfig;
    }
}
  1. 创建DataAccessHandler用于控制权限
@Component
public class CustomDataAccessHandler implements DataAccessHandler {

    @Override
    public boolean isSupport(DataAccessConfig access) {
        return access instanceof MyDataAccessConfig;
    }

    @Override
    public boolean handle(DataAccessConfig access, AuthorizingContext context) {
        MyDataAccessConfig custom = ((MyDataAccessConfig) access);

        //可以通过context中的属性,进行数据权限操作,如修改请求的参数等。
    
        //返回true 认证通过
        return true;
    }
}

自定义登录逻辑

hsweb 默认提供了授权的http接口:authorize/login,使用Post提交 username,password进行登录授权。 授权过程中,会通过触发事件的方式来实现自定义的操作,如:用户名密码解密,验证码验证等操作.

类名 说明
AuthorizationDecodeEvent 接收到请求参数时
AuthorizationBeforeEvent 验证密码前触发
AuthorizationFailedEvent 授权验证失败时触发
AuthorizationSuccessEvent 授权成功时触发
AuthorizationExitEvent 用户注销时触发

例如:

@Component
public class CustomAuthorizationSuccessListener implements ApplicationListener<AuthorizationSuccessEvent>{
        @Override
        public void onApplicationEvent(AuthorizationSuccessEvent event) {
            Authentication authentication=event.getAuthentication();
            //....
            System.out.println(authentication.getUser().getName()+"登录啦");
        }
}

高级应用

自定义token策略实现前后分离

UserTokenGenerator: 在用户登录成功后,根据token_type参数,调用对应的UserTokenGenerator生成token.默认提供的是SessionIdUserTokenGenerator,使用sessionId作为token.

UserTokenParser: 用于在接收到请求的时候,解析请求中的token,

  1. 自定义UserTokenGenerator
@Component
public class SimpleUserTokenGenerator implements UserTokenGenerator {

    private int timeout = 30 * 60 * 1000;

    @Override
    public String getSupportTokenType() {
       // 登录时,请求参数为 token_type = token 时,此配置生效
        return "token";
    }

    @Override
    public GeneratedToken generate(Authentication authentication) {
        String token = IDGenerator.MD5.generate();

        return new GeneratedToken() {
            @Override
            public Map<String, Object> getResponse() {
                //返回给前端的参数,前端拿到此参数后自行处理
                return Collections.singletonMap("token", token);
            }

            @Override
            public String getToken() {
                return token;
            }

            @Override
            public int getTimeout() {
                // token 超时时间,超过时间没有请求时,自动失效
                return timeout;
            }
        };
    }
}
  1. 自定义UserTokenParser
public class SimpleUserTokenParser implements UserTokenParser {
    @Override
    public ParsedToken parseToken(HttpServletRequest request) {
        //获取参数中的token
        String token = request.getParameter("token");

        if(StringUtils.isEmpty(token))return null;

        return () -> token;
    }
}
  1. 在请求autorize/login的时候,指定参数token_type=token,上述自定义配置将生效。请求结果:
{
"result":{
  "token":"abc",   "userId":"user id"
 },
"status":200
}

result.token记录下来,在接下来的请求参数中都带上: ?token=abc 即可

启动服务时同步权限定义信息到数据库

启动服务时,自动将权限定义(Controller上的@Authorize注解)同步到数据库中的权限表。避免每次新增权限都要去数据库里添加的麻烦.

  1. hsweb-system-authorization-starter已经实现了此功能: 修改配置文件以开启此功能
hsweb:
  authorize:
    auto-parse: true # 启动时解析权限定义,并触发AuthorizeDefinitionInitializedEvent事件
    sync: true # 监听了AuthorizeDefinitionInitializedEvent事件,并自动同步到数据库中
  1. 你也可以自行实现同步的逻辑: 实现 ApplicationListener<AuthorizeDefinitionInitializedEvent>即可

hsweb 3.0

 3.0,全新的架构
 模块化,更细,更轻
 吸取经验,优化功能
  1. 增删改查
  2. 权限控制
  3. 访问日志
  4. 动态数据源
  5. 常用并发工具
  6. 消息封装
  7. 其他工具
Clone this wiki locally