需求:
请求加上Authorization头部,按指定格式添加校验内容。Authorization包含以下几个方面信息:
  • 校验方式:固定为HMAC-SHA256
  • timestamp:当前时间的13位毫秒时间戳
  • signature:请求签名,按指定方式生成
Authorization格式具体为:
Authorization:HMAC-SHA256,${timestamp},${signature}
private boolean authorizationValidation(HttpServletRequest request) {
    CachedBodyHttpServletRequest cachedRequest = (CachedBodyHttpServletRequest) request;
    String authorizationHeader = request.getHeader("Authorization");try {
      // 解析 Authorization 值
      String[] authValues = authorizationHeader.split(",");
      String timestamp = authValues[1];
      String body = cachedRequest.getBody();
      if (body == null) {
        body = "";
      }
      String receivedSignature = authValues[2];
      log.info("[PearlBlockController.authorizationValidation]请求的receivedSignature: {}",
          JsonUtils.obj2String(receivedSignature));
      String path = request.getRequestURI();
      String query = request.getQueryString();
      if (StringUtils.isNotBlank(query)) {
        path += "?" + query;
      }
      // 构建参与签名的字符串
      StringBuilder stringToSign = new StringBuilder();
      stringToSign.append(path).append("\n");
      stringToSign.append(timestamp).append("\n");
      stringToSign.append(body).append("\n");
      log.info("[PearlBlockController.authorizationValidation]stringToSign: {}",
          JsonUtils.obj2String(stringToSign));
      // 使用 HMAC-SHA256 算法进行签名
      SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8),
          algorithm);
      Mac mac = Mac.getInstance(algorithm);
      mac.init(signingKey);
      byte[] signatureBytes = mac.doFinal(stringToSign.toString().getBytes(StandardCharsets.UTF_8));

      // 对签名进行 Base64 编码
      String calculatedSignature = Base64.getEncoder().encodeToString(signatureBytes);// 对比签名值
      if (calculatedSignature.equals(receivedSignature)) {return true;
      }
    } catch (NoSuchAlgorithmException | InvalidKeyException e) {
      e.printStackTrace();
      log.info(e.getMessage());
    }
    return false;
  }
public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper {

  private final byte[] cachedBody;

  public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {
    super(request);
    InputStream requestInputStream = request.getInputStream();
    this.cachedBody = StreamUtils.copyToByteArray(requestInputStream);
  }

  @Override
  public ServletInputStream getInputStream() {
    return new CachedBodyServletInputStream(this.cachedBody);
  }

  @Override
  public BufferedReader getReader() throws IOException {
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.cachedBody);
    return new BufferedReader(new InputStreamReader(byteArrayInputStream));
  }

  public String getBody() {
    return new String(cachedBody);
  }
}
public abstract class StreamUtils {
    public static final int BUFFER_SIZE = 4096;

    public StreamUtils() {
    }

    public static byte[] copyToByteArray(InputStream in) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
        copy(in, out);
        return out.toByteArray();
    }

    public static int copy(InputStream in, OutputStream out) throws IOException {
        int byteCount = 0;
        byte[] buffer = new byte[4096];

        int bytesRead;
        for(boolean var4 = true; (bytesRead = in.read(buffer)) != -1; byteCount += bytesRead) {
            out.write(buffer, 0, bytesRead);
        }

        out.flush();
        return byteCount;
    }
}

 

posted on 2023-10-12 17:33  一直深夜吃食的喵  阅读(210)  评论(0编辑  收藏  举报