基于角色访问控制RBAC权限模型的动态资源访问管理的实现用户拥有不同的权限。本文主要介绍crudapi中基于RBAC的动态权限管理的实现。RBAC概述简介RBAC权限模型(Role-BasedAccessControl)是:基于角色的访问控制。模型中有几个关键术语:用户:系统接口和访问权限操作者权限:能够访问接口或执行操作的授权资格角色:具有相同操作权限的用户的总称。一个或多个角色一个角色包含多个用户一个角色拥有多个权限一个权限属于多个角色表单配置系统有5个内置表单。这些表单与权限相关,与具体的业务资源资源无关。url是ANT格式的表达式,用于配置url来判断是否拥有某个资源的权限。User用户用户表记录登录用户信息角色角色角色用户角色行userRoleLine用户和角色中间表,参考前面的表关系管理,使用两个一对多建立多对多关系,角色资源行roleResourceLine角色和资源中间表,同样使用两个一对多建立多对多关系的表关系,原表目标表关系useruserRoleLine一对多userRoleLinerole多对一roleroleResourceLine一对多roleResourceLineresource多对一权限控制原则根据登录用户偏好的角色列表,每个A角色对应多个资源,最终用户的权限叠加在多个角色对应的资源上。如果你有某个资源权限,就返回数据,否则会提示没有权限。默认情况下,如果没有匹配到资源,则表示该资源不需要特殊权限,只需要以用户身份登录即可。验证并添加客户资源,ANTurl为/api/business/customer/*,操作为,说明GET、PATCH、DELETE、POST都需要授权。如果操作为DELETE,则该值控制DELETE操作,其他操作不受限制。通过UI访问客户时,提示没有权限,符合预期效果。添加具有客户访问权限的角色“客户管理员”。给“超级管理员”添加“客户管理员”的角色,这样“超级管理员”就有了因为用户重新分配了角色,需要注销重新登录。登录后,他又可以正常访问客户资源了。核心源码@Slf4j@ComponentpublicclassDynamicSecurityMetadataSourceimplementsFilterInvocationSecurityMetadataSource{privatestaticMapconfigAttributeMap=null;@AutowiredprivateDynamicSecurityServicedynamicSecurityService;@PostConstructpublicvoidloadDataSource(){configAttributeMap=dynamicSecurityService.loadDataSource();}publicvoidclearDataSource(){log.info("DynamicSecurityMetadataSourceclearDataSource");configAttributeMap.clear();配置属性映射=空;}@OverridepublicCollectiongetAttributes(Objecto)抛出IllegalArgumentException{if(configAttributeMap==null){this.loadDataSource();}ListconfigAttributes=newArrayList<>();FilterInvocationfi=(FilterInvocation)o;字符串方法=fi.getRequest().get方法();log.info("getAttributes方法="+方法);//获取当前访问路径Stringurl=fi.getRequestUrl();Stringpath=URLUtil.getPath(url)+"_"+方法;log.info("getAttributesurl="+url);log.info("getAttributes路径="+路径);PathMatcherpathMatcher=newAntPathMatcher();Iteratoriterator=configAttributeMap.keySet().iterator();//获取访问路径所需的资源while(iterator.hasNext()){Stringpattern=iterator.next();if(pathMatcher.match(pattern,path)){log.info("匹配成功="+pattern+","+path);configAttributes.add(configAttributeMap.get(模式));}}//未设置操作请求权限,返回空集合returnconfigAttributes;}@OverridepublicCollectiongetAllConfigAttributes(){返回空值;}@Override公共布尔值支持s(ClassaClass){返回真;}}继承FilterInvocationSecurityMetadataSource,实现getAttributes接口,通过httpurl加http方法进行匹配@Slf4j@ComponentpublicclassDynamicAccessDecisionManagerimplementsAccessDecisionManager{@Overridepublicvoiddecide(AuthenticationObjectauthentication,CollectionconfigAttributes)throwsAccessDeniedException,InsufficientAuthenticationException{//当接口未配置资源直接释放返回;}FilterInvocationfi=(FilterInvocation)object;字符串方法=fi.getRequest().getMethod();log.info("决定方法="+方法);ListneedAuthorityList=newArrayList();迭代器迭代器=配置属性。迭代器();while(iterator.hasNext()){ConfigAttributeconfigAttribute=iterator.next();//比较访问需要的资源和用户拥有的资源StringneedAuthority=configAttribute.getAttribute();needAuthorityList.add(needAuthority);对于(GrantedAuthoritygrantedAuthority:authentication.getAuthorities()){if(needAuthority.trim().equals(grantedAuthority.getAuthority())){返回;}}}thrownewAccessDeniedException("抱歉,您没有资源:"+String.join(",",needAuthorityList)+"访问权限!");}@Overridepublicbooleansupports(ConfigAttributeconfigAttribute){返回真;}@Overridepublicbooleansupports(ClassaClass){returntrue;}}继承AccessDecisionManager,实现decide接口,比较访问需要的资源和用户拥有的资源。如果你有权限,你就会被释放,否则会提示你没有权限。小结本文介绍了crudapi中RBAC的实现原理。用户、角色、资源等形式,通过配置实现基本的CRUD功能,最终实现动态权限的精细化管理。因为用户、角色等表与业务无关,所以会作为系统内置的表单使用。附上demo演示本系统是一个产品级的零代码平台。不同于自动代码生成器,它不需要生成Controller、Service、Repository、Entity等业务代码。业务独立的CRUDRESTfulAPI。官网地址:https://crudapi.cn测试地址:https://demo.crudapi.cn/crudapi/login