ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

springboot修改接口入参出参实现入参加密出参解密

2022-07-10 10:33:02  阅读:264  来源: 互联网

标签:body return springboot 密出 Decrypt 解密 接口 public 参出


一、背景

针对项目已经开发完的接口,都需要加上传输数据加密的功能,对接口入参进行AES解密,对接口出参进行加密。考虑到尽量改动少点,使用自定义注解结合springmvc里的RequestBodyAdvice和ResponseBodyAdvice两个类进行实现。

RequestBodyAdvice允许针对接口请求体被读取之前进行修改,ResponseBodyAdvice允许接口出参在被返回之前进行修改。

二、实现

1、新建两个自定义注解类,用来标记哪些接口需要进行加密解密。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Encrypt {
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.PARAMETER})
@Documented
public @interface Decrypt {
}

注意:@Decrypt配置的作用域是方法和参数上,@Encrypt则是只在方法上。

2、新建自定义DecryptRequestAdvice类继承RequestBodyAdviceAdapter,进行入参解密

@ControllerAdvice
@Slf4j
public class DecryptRequestAdvice extends RequestBodyAdviceAdapter {

    @Autowired
    private AesUtil aesUtil;

    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 当某个接口方法或参数上加了@Decrypt注解,才进行解密操作
     return methodParameter.hasMethodAnnotation(Decrypt.class) || methodParameter.hasParameterAnnotation(Decrypt.class); } @Override public HttpInputMessage beforeBodyRead(final HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException { InputStream inputStream = inputMessage.getBody(); byte[] bytes = new byte[inputStream.available()]; inputStream.read(bytes); String requestBody = new String(bytes); try { // 结合自己业务针对获取到的requestBody内容进行修改解密等操作 String decryptData = aesUtil.decrypt(requestBody , "www.cnblogs.com/shamo89");
       // 把入参修改为解密后的内容
            final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decryptData.getBytes());
            return new HttpInputMessage() {
                @Override
                public InputStream getBody() throws IOException {
                    return byteArrayInputStream;
                }

                @Override
                public HttpHeaders getHeaders() {
                    return inputMessage.getHeaders();
                }
            };
        } catch (Exception e) {
            log.error("接口入参解密出错:{}", Throwables.getStackTraceAsString(e));
        }

        return super.beforeBodyRead(inputMessage, parameter, targetType, converterType);
    }
}

3、新建自定义EncryptResponseAdvice类继承ResponseBodyAdvice,进行出参加密

这里的R是自定义的接口返回封装类

 

@ControllerAdvice
@Slf4j
public class EncryptResponseAdvice implements ResponseBodyAdvice<R> {

    @Autowired
    private AesUtil aesUtil;

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
     // 只有接口上加了@Encrypt注解才进行出参加密操作
return returnType.hasMethodAnnotation(Encrypt.class); } @Override public R beforeBodyWrite(R body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { try { if (body.getData() != null) { log.info("接口加密前返回的数据:{}", JSONUtil.toJsonStr(body.getData())); String encStr = aesUtil.encrypt(JSONUtil.toJsonStr(body.getData()), "www.cnblogs.com/shamo89");
                log.info("接口加密后返回的数据:{}", encStr);
                body.setData(encStr);
            }
        } catch (Exception e) {
            log.error("接口返回数据加密出错:{}", Throwables.getStackTraceAsString(e));
        }
        return body;
    }
}

 

4、controller接口

@PostMapping("/test")
    @ApiOperation(value = "测试接口加密解密")
    @Encrypt
    public R<UserInfoDTO> test(@Decrypt @RequestBody @Valid QueryVO vo) {
        UserInfoDTO convert = Convert.convert(UserInfoDTO.class, vo);
return new R(convert); }

三、原理说明

上面那两个advice类型,都要使用@ControllerAdvice注解进行修饰,它其实是一个实现特殊功能的@Component,只是针对controller进行拦截,本质还是aop,我们平常使用的全局异常处理类@ExceptionHandler,GlobalExceptionHandler,也是配合该注解使用。

另外这边入参拦截修改,只针对@RequestBody修饰的body进行处理,同时返回一样,要被@ResponseBody修饰,如果你使用的是@RestController,那就不需要再加了。

标签:body,return,springboot,密出,Decrypt,解密,接口,public,参出
来源: https://www.cnblogs.com/shamo89/p/16462690.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有