前端请求后端时,会直接使用Id访问接口,Id数据为数据库自增Id,所以这样访问会有数据泄露风险。评估工作量后,决定采用后端返回数据时,对Id进行加密,前端请求使用Id时传输返回的加密数据。
部分接口在获取定义http接口时,采用了路径参数的方式,需要在调用Controller方法前,对数据进行解密。
决定采用HandlerMethodArgumentResolver进行数据操作处理,经查找,Spring中提供了PathVariableMethodArgumentResolver用于处理路径参数,由于并不是所有的路径参数都需要进行处理,故通过自定义注解进行判定。
public class CryptoPathVariableMethodArgumentResolver extends PathVariableMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(PathVariable.class) && parameter.hasParameterAnnotation(IdParameterCrypto.class);
}
@Override
protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
Object content = super.resolveName(name, parameter, request);
IdSecretDto<Object> dto = ParameterCryptoHelper.decodeIdAndCheckUserId((String) content);
return dto.getId();
}
}
supportsParameter()
用于判断方法是否满足条件
resolveName()
由PathVariableMethodArgumentResolver
提供用于解析地址参数提取出来的数据,将处理后的数据返回,即可正确的提供给调用接口了。
在进行HandlerMethodArgumentResolver的注册时,一开始通过实现WebMvcConfigurer,重写addArgumentResolvers的方法,但是发现采用此种方法注册之后,自定义的HandlerMethodArgumentResolver无法生效。
参考两篇博客后,将注册方式进行修改
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
@PostConstruct
public void init() {
List<HandlerMethodArgumentResolver> argumentResolvers = requestMappingHandlerAdapter.getArgumentResolvers();
List<HandlerMethodArgumentResolver> list = new ArrayList<>();
list.add(0, new CryptoPathVariableMethodArgumentResolver());
list.addAll(argumentResolvers);
requestMappingHandlerAdapter.setArgumentResolvers(list);
}
参考:
- https://zhuanlan.zhihu.com/p/581486089
- https://mp.weixin.qq.com/s?__biz=MzI1MTY1Njk4NQ==&mid=2247506143&idx=1&sn=d2b3e216a64037aa20d4e8e6b7e9eb17&chksm=e9ed36a9de9abfbfcb24d0c10469ade58ec99c721cd3273b50d33475e9ebd6a2afa0409ade5a&token=1230955387&lang=zh_CN#rd