SpringBoot中间件之封装统一白名单配置
作者:看表该更新博客了
这篇文章主要介绍了SpringBoot中间件封装统一白名单配置,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
背景
上线初期提供可配置的白名单用户进行访问验证,把控整体运行风险。
解决痛点:
APOLLO企业控制也可以,多个业务功能,要配置多个apollo,如ASwitch,BSwitch,这样会非常耗时耗力,而且等功能稳定,要放开企业/用户限制时,只能将APOLLO的值置为空串或者某个特殊值(已表示对全部企业/用户放开),日后会残留在代码里。
方案设计
白名单属于业务系统开发过程中可重复使用的通用功能,所以我们把这样的工具型功能提炼为技术组件,各个需要的使用此功能的系统引入此组件。
技术点
自定义注解、切面和springboot读取配置文件的处理
代码实现
1.切面
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DoWhiteList { /** * key:当前接口入参需要提取的属性 * @return */ String key() default ""; /** * returnJson: 拦截用户请求后返回的提示msg * @return */ String returnJson() default ""; }
扩展
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
字如其名,目标,即自定义注解DoWhiteList是要作用在类、接口还是方法上
2.配置类
/** * @ConfigurationProperties:用于创建指定前缀的自定义配置信息,这样就在ymL或者properties中读取到配置信息 */ @ConfigurationProperties("com.whitelist") public class WhiteListProperties { private String users; public String getUsers() { return users; } public void setUsers(String users) { this.users = users; } }
/** * * @ConditionalOnMissingBean * 只会实例化一个Bean对象 */ @Configuration @EnableConfigurationProperties(WhiteListProperties.class) public class WhiteListAutoConfigure { @Bean("whiteListConfig") @ConditionalOnMissingBean public String whiteListConfig(WhiteListProperties properties) { return properties.getUsers(); } }
3.切面
@Aspect @Component public class DoJoinPoint { private Logger logger = LoggerFactory.getLogger(DoJoinPoint.class); @Resource private String whiteListConfig; @Pointcut("@annotation(cn.bugstack.middleware.whitelist.annotation.DoWhiteList)") public void aopPoint() { } @Around("aopPoint()") public Object doRouter(ProceedingJoinPoint jp) throws Throwable { // 获取内容 Method method = getMethod(jp); DoWhiteList whiteList = method.getAnnotation(DoWhiteList.class); // 获取字段值 String keyValue = getFiledValue(whiteList.key(), jp.getArgs()); logger.info("middleware whitelist handler method:{} value:{}", method.getName(), keyValue); if (null == keyValue || "".equals(keyValue)) return jp.proceed(); String[] split = whiteListConfig.split(","); // 白名单过滤 for (String str : split) { if (keyValue.equals(str)) { return jp.proceed(); } } // 拦截 return returnObject(whiteList, method); } private Method getMethod(JoinPoint jp) throws NoSuchMethodException { Signature sig = jp.getSignature(); MethodSignature methodSignature = (MethodSignature) sig; return jp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes()); } // 返回对象 private Object returnObject(DoWhiteList whiteList, Method method) throws IllegalAccessException, InstantiationException { Class<?> returnType = method.getReturnType(); String returnJson = whiteList.returnJson(); if ("".equals(returnJson)) { return returnType.newInstance(); } return JSON.parseObject(returnJson, returnType); } // 获取属性值 private String getFiledValue(String filed, Object[] args) { String filedValue = null; for (Object arg : args) { try { if (null == filedValue || "".equals(filedValue)) { filedValue = BeanUtils.getProperty(arg, filed); } else { break; } } catch (Exception e) { if (args.length == 1) { return args[0].toString(); } } } return filedValue; } }
测试
白名单中只允许userId为123的访问
测试场景一
userId为123:
切面拦截判断该userid在白名单配置中,放行
测试场景二
userId为【非123】:
切面拦截判断该userid不在白名单配置中,拦截
总结
日后每上线一个新功能/接口,用该注解可以实现批量梯度控制访问来把控整体运行风险,等功能稳定后,将该注解干掉即可。
到此这篇关于SpringBoot中间件——封装统一白名单配置的文章就介绍到这了,更多相关SpringBoot白名单配置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!