一.需求
请求加上Authorization头部,按指定格式添加校验内容。Authorization包含以下几个方面信息:
校验方式:固定为HMAC-SHA256
timestamp:当前时间的13位毫秒时间戳
signature:请求签名,按指定方式生成
二.实现
final String secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
final String algorithm = "HmacSHA256";
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];
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");
// 使用 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;
}
}
文章介绍了如何在HTTP请求中添加Authorization头部,使用HMAC-SHA256算法生成并验证签名,包括获取时间戳、构造签名字符串、计算签名并进行比对的过程。
852

被折叠的 条评论
为什么被折叠?



