用于实现类似@RequestBody的作用,前后端在没有https的情况下,利用rsa非对称加密,实现数据安全性

  1. 首先创建注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /**
    * RSA加密数据解密
    *
    * @author: 李涛
    * @version: 2019年06月19日 10:44
    */
    @Target({ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface RequestEncrypt {

    }
  2. 利用spring参数处理器,实现接口,拦截该注解的参数,处理并返回

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    /**
    * 处理加密数据,参数
    *
    * @author: 李涛
    * @version: 2019年06月19日 10:40
    */
    @Component
    public class HandlerMethodArgumentCustomer implements HandlerMethodArgumentResolver {

    private static final Logger LOG = LoggerFactory.getLogger(HandlerMethodArgumentCustomer.class);

    @Autowired
    private ISysSignSV sysSignSV;

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
    if (parameter.hasParameterAnnotation(RequestEncrypt.class)) {
    return true;
    }
    return false;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
    HttpServletRequest nativeRequest = webRequest.getNativeRequest(HttpServletRequest.class);
    String contentType = nativeRequest.getContentType();
    if (!contentType.equals(MediaType.APPLICATION_JSON_VALUE)
    && !contentType.equals(MediaType.APPLICATION_JSON_UTF8_VALUE)
    ) {
    throw new MediaTypeNotSupportedStatusException("期望请求为application/json");
    }
    // 加密数据
    byte[] body = ServletUtils.getRequestBody();
    String jsonData = IOUtils.toString(body);
    if (body.length == 0 || StringUtils.isBlank(jsonData) || jsonData.length() == 0) {
    return null;
    }
    // 获取当前登录用户的公私钥。如果没空,在header里取
    Object appKeyObj = ShiroUtil.getSession().getAttribute(Global.APP_KEY);
    Object appSercetObj = ShiroUtil.getSession().getAttribute(Global.APP_SERCET);
    String appKey = appKeyObj == null ? null : String.valueOf(appKeyObj);
    String appSercet = appSercetObj == null ? null : String.valueOf(appSercetObj);
    if (StringUtils.isBlank(appKey) || StringUtils.isBlank(appSercet)) {
    appKey = ServletUtils.getHeader("appKey");
    if (StringUtils.isBlank(appKey)) {
    return null;
    } else {
    // 获取私钥
    SysSign sysSign = sysSignSV.findByModel(SysSignModel.builder().appKey(appKey).includeColumns("app_secret").build());
    appSercet = sysSign.getAppSecret();
    }
    }

    try {
    RSA rs = new RSA(appSercet, appKey);
    byte[] decrypt = rs.decrypt(jsonData, KeyType.PrivateKey);
    jsonData = IOUtils.toString(decrypt);
    } catch (Exception e) {
    LOG.error("Rsa加密数据解密异常");
    }
    return JSONObject.parseObject(jsonData, parameter.getParameterType());
    }
    }
  3. 将参数处理器,加入到spring的拦截器调用链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 向MVC中添加自定义组件
*/
@Component
public class WebMvcConfig implements WebMvcConfigurer {

@Autowired
private HandlerMethodArgumentCustomer handlerMethodArgumentCustomer;

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(handlerMethodArgumentCustomer);
}

}

ok