背景:
项目需要实现不同用户,有不同的权限,查看不同的数据列表
实现:
通过实现Interceptor,对所有的请求接口参数继承DataAuthorityDTO,在请求接口之前设置一些字段值,用于区分不同的用户权限,再去查询数据库
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 账号权限拦截器
*/
@Slf4j
@Component
public class DataAuthorityInterceptor implements ApiInterceptor {
@Resource
public DataAuthorityService dataAuthorityService;
/**
* 平台后台权限dictId
*/
private static final String CMA_PLATFORM_BACK_CODE = "CMA_PLATFORM_BACK_DATA_AUTHORITY";
/**
* 客户后台权限dictId
*/
private static final String CMA_CUSTOMER_CODE = "CMA_CUSTOMER_DATA_AUTHORITY";
/**
* 应用前台权限dictId
*/
private static final String CMA_FRONT_CODE = "CMA_FRONT_DATA_AUTHORITY";
@Override
public void preHandle(String url, Method method, Object[] args) {
log.info("账号权限拦截,{} {}",url,method);
String methodName = method.getDeclaringClass().getName();
String dictCode = getDictCode(methodName);
try{
//调用接口查询用户权限码
List<String> codes = dataAuthorityService.getCodesByUserId(HttpContext.getUserContext().getUserId(), dictCode);
log.info("用户数据权限码,{} {}",codes,url);
if(!ListHelper.isNullOrEmpty(codes)){
String code = codeStrategyFactory(dictCode).choseCode(codes);
strategyFactory(code).dealArgs(args);
}
//没有数据权限,特殊处理
if(ListHelper.isNullOrEmpty(codes)){
for (Object arg : args) {
if(DataAuthorityDTO.class.isAssignableFrom(arg.getClass())) {
DataAuthorityDTO arg1 = (DataAuthorityDTO) arg;
arg1.setId("0");
}
}
}
}catch (Exception e){
log.error(e.getMessage());
}
}
private static final String FRONT = "front";
private static final String CUSTOMER_BACK = "customerback";
/**
* 分4大权限板块:平台后台background; 应用前台:front; 客户后台:customerback; 公共板块:common,不涉及权限拦截
* @param methodName method
* @return code
*/
private String getDictCode(String methodName) {
if (methodName.contains(FRONT))
return CMA_FRONT_CODE;
if (methodName.contains(CUSTOMER_BACK))
return CMA_CUSTOMER_CODE;
return CMA_PLATFORM_BACK_CODE;
}
/**
* 选择数据权限工厂
* @param dictCode 权限dictId
* @return
*/
public ChoseCodeStrategy codeStrategyFactory(String dictCode){
if (dictCode.equals(CMA_FRONT_CODE))
return new FrontStrategy();
if (dictCode.equals(CMA_CUSTOMER_CODE))
return new CustomerStrategy();
return new PlatformBackStrategy();
}
/**
* 具体策略
*/
static class FrontStrategy implements ChoseCodeStrategy{
@Override
public String choseCode(List<String> codes) {
if(codes.contains(ItemCodeConst.CODE_ALL))
return ItemCodeConst.CODE_ALL;
if(codes.contains(ItemCodeConst.CODE_ORGAN_PLATFORM))
return ItemCodeConst.CODE_ORGAN_PLATFORM;
if(codes.contains(ItemCodeConst.CODE_DEPT_PLATFORM) && codes.contains(ItemCodeConst.CODE_ORGAN))
return ItemCodeConst.CODE_ORGAN_PLATFORM;
if(codes.contains(ItemCodeConst.CODE_DEPT_PLATFORM))
return ItemCodeConst.CODE_DEPT_PLATFORM;
if(codes.contains(ItemCodeConst.CODE_SELF_PLATFORM) && codes.contains(ItemCodeConst.CODE_ORGAN))
return ItemCodeConst.CODE_ORGAN_PLATFORM;
if(codes.contains(ItemCodeConst.CODE_SELF_PLATFORM) && codes.contains(ItemCodeConst.CODE_DEPT))
return ItemCodeConst.CODE_DEPT_PLATFORM;
if(codes.contains(ItemCodeConst.CODE_SELF_PLATFORM))
return ItemCodeConst.CODE_SELF_PLATFORM;
if(codes.contains(ItemCodeConst.CODE_PLATFORM) && codes.contains(ItemCodeConst.CODE_ORGAN))
return ItemCodeConst.CODE_ORGAN;
if(codes.contains(ItemCodeConst.CODE_PLATFORM) && codes.contains(ItemCodeConst.CODE_DEPT))
return ItemCodeConst.CODE_DEPT;
if(codes.contains(ItemCodeConst.CODE_PLATFORM) && codes.contains(ItemCodeConst.CODE_SELF))
return ItemCodeConst.CODE_SELF;
if(codes.contains(ItemCodeConst.CODE_ORGAN))
return ItemCodeConst.CODE_ORGAN;
if(codes.contains(ItemCodeConst.CODE_DEPT))
return ItemCodeConst.CODE_DEPT;
if(codes.contains(ItemCodeConst.CODE_PLATFORM))
return ItemCodeConst.CODE_PLATFORM;
return ItemCodeConst.CODE_SELF;
}
}
static class CustomerStrategy implements ChoseCodeStrategy{
@Override
public String choseCode(List<String> codes) {
if(codes.contains(ItemCodeConst.CODE_ORGAN))
return ItemCodeConst.CODE_ORGAN;
if(codes.contains(ItemCodeConst.CODE_DEPT))
return ItemCodeConst.CODE_DEPT;
return ItemCodeConst.CODE_SELF;
}
}
static class PlatformBackStrategy implements ChoseCodeStrategy{
@Override
public String choseCode(List<String> codes) {
if(codes.contains(ItemCodeConst.CODE_ALL))
return ItemCodeConst.CODE_ALL;
if(codes.contains(ItemCodeConst.CODE_ORGAN))
return ItemCodeConst.CODE_ORGAN;
if(codes.contains(ItemCodeConst.CODE_DEPT))
return ItemCodeConst.CODE_DEPT;
return ItemCodeConst.CODE_SELF;
}
}
/**
* 数据权限码策略 - 策略模式
*/
interface ChoseCodeStrategy {
/**
* 选择具体的数据权限
* @param codes 所有的数据权限
* @return 具体的数据权限
*/
String choseCode(List<String> codes);
}
/**HandlerInterceptor
* 简单工厂
* @param code code
* @return DataAuthorityStrategy
*/
public DataAuthorityStrategy strategyFactory(String code) {
if (ItemCodeConst.CODE_PLATFORM.equals(code))
return new PlatformStrategy();
if (ItemCodeConst.CODE_DEPT_PLATFORM.equals(code))
return new DeptPlatformStrategy();
if (ItemCodeConst.CODE_SELF.equals(code))
return new SelfStrategy();
if (ItemCodeConst.CODE_ORGAN.equals(code))
return new OrganStrategy();
if (ItemCodeConst.CODE_ORGAN_PLATFORM.equals(code))
return new OrganPlatformStrategy();
if (ItemCodeConst.CODE_SELF_PLATFORM.equals(code))
return new SelfPlatformStrategy();
if (ItemCodeConst.CODE_DEPT.equals(code))
return new DeptStrategy();
return new AllStrategy();
}
/**
* 数据权限策略 - 策略模式
*/
interface DataAuthorityStrategy {
/**
* 处理权限入参
* @param args args
* @author zx
*/
void dealArgs(Object[] args);
}
/**
* 具体策略
*/
static class PlatformStrategy implements DataAuthorityStrategy{
@Override
public void dealArgs(Object[] args) {
for (Object arg : args) {
if(DataAuthorityDTO.class.isAssignableFrom(arg.getClass())) {
DataAuthorityDTO arg1 = (DataAuthorityDTO) arg;
arg1.setSourceType(0);
//arg1.setOrganId(PLATFORM_ORGAN_ID);
}
}
}
}
static class DeptPlatformStrategy implements DataAuthorityStrategy{
@Override
public void dealArgs(Object[] args) {
for (Object arg : args) {
if(DataAuthorityDTO.class.isAssignableFrom(arg.getClass())) {
DataAuthorityDTO arg1 = (DataAuthorityDTO) arg;
arg1.setDeptIdOr(HttpContext.getAndCheckUserContext().getDeptId());
}
}
}
}
static class SelfStrategy implements DataAuthorityStrategy{
@Override
public void dealArgs(Object[] args) {
for (Object arg : args) {
if(DataAuthorityDTO.class.isAssignableFrom(arg.getClass())) {
DataAuthorityDTO arg1 = (DataAuthorityDTO) arg;
// if (arg1.getIsPlatform()) {
// arg1.setOrganId(PLATFORM_ORGAN_ID);
// } else {
arg1.setCreator(HttpContext.getAndCheckUserContext().getUserId());
// }
}
}
}
}
static class OrganStrategy implements DataAuthorityStrategy{
@Override
public void dealArgs(Object[] args) {
for (Object arg : args) {
if(DataAuthorityDTO.class.isAssignableFrom(arg.getClass())) {
DataAuthorityDTO arg1 = (DataAuthorityDTO) arg;
// if (arg1.getIsPlatform()) {
// arg1.setOrganId(PLATFORM_ORGAN_ID);
// } else {
arg1.setOrganId(HttpContext.getAndCheckUserContext().getOrganId());
// }
}
}
}
}
static class OrganPlatformStrategy implements DataAuthorityStrategy{
@Override
public void dealArgs(Object[] args) {
for (Object arg : args) {
if(DataAuthorityDTO.class.isAssignableFrom(arg.getClass())) {
DataAuthorityDTO arg1 = (DataAuthorityDTO) arg;
//String[] strings = {HttpContext.getAndCheckUserContext().getOrganId(), PLATFORM_ORGAN_ID};
arg1.setOrganIds(Arrays.asList(HttpContext.getAndCheckUserContext().getOrganId()));
}
}
}
}
static class SelfPlatformStrategy implements DataAuthorityStrategy{
@Override
public void dealArgs(Object[] args) {
for (Object arg : args) {
if(DataAuthorityDTO.class.isAssignableFrom(arg.getClass())) {
DataAuthorityDTO arg1 = (DataAuthorityDTO) arg;
arg1.setCreatorOr(HttpContext.getAndCheckUserContext().getUserId());
}
}
}
}
static class DeptStrategy implements DataAuthorityStrategy{
@Override
public void dealArgs(Object[] args) {
for (Object arg : args) {
if(DataAuthorityDTO.class.isAssignableFrom(arg.getClass())) {
DataAuthorityDTO arg1 = (DataAuthorityDTO) arg;
// if (arg1.getIsPlatform()) {
// arg1.setOrganId(PLATFORM_ORGAN_ID);
// } else {
arg1.setDeptId(HttpContext.getAndCheckUserContext().getDeptId());
// }
}
}
}
}
static class AllStrategy implements DataAuthorityStrategy{
@Override
public void dealArgs(Object[] args) {
for (Object arg : args) {
if(DataAuthorityDTO.class.isAssignableFrom(arg.getClass())) {
DataAuthorityDTO arg1 = (DataAuthorityDTO) arg;
// if (arg1.getIsPlatform()) {
// arg1.setOrganId(PLATFORM_ORGAN_ID);
// }
}
}
}
}
}