club.zhcs.rop.checker.ROPServerRSASignatureVerifier Maven / Gradle / Ivy
package club.zhcs.rop.checker;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import org.nutz.http.Http;
import org.nutz.lang.Lang;
import org.nutz.lang.Streams;
import org.nutz.lang.Strings;
import org.nutz.log.Logs;
import club.zhcs.rop.core.ROPConsts;
import club.zhcs.rop.core.signer.KeyPairFetcher;
import club.zhcs.rop.core.signer.SignerHelper;
/**
*
* @author Kerbores([email protected])
*
*/
public class ROPServerRSASignatureVerifier implements ServerSignatureVerifier {
ServerKeyPairFetcher fetcher;
public ROPServerRSASignatureVerifier(ServerKeyPairFetcher fetcher) {
super();
this.fetcher = fetcher;
}
@Override
public boolean verification(HttpServletRequest request) {
if (Strings.isBlank(request.getHeader(ROPConsts.PUBLIC_KEY_KEY))
|| Strings.isBlank(request.getHeader(ROPConsts.TS_KEY))
|| Strings.isBlank(request.getHeader(ROPConsts.METHOD_KEY))
|| Strings.isBlank(request.getHeader(ROPConsts.NONCE_KEY))
|| Strings.isBlank(request.getHeader(ROPConsts.SIGN_KEY))) {
return false;
}
String sign = request.getHeader(ROPConsts.SIGN_KEY);
Logs.get().debugf("Expected sign is %s", sign);
return verification(request.getHeader(ROPConsts.PUBLIC_KEY_KEY),
request.getHeader(ROPConsts.TS_KEY),
request.getHeader(ROPConsts.METHOD_KEY),
request.getHeader(ROPConsts.NONCE_KEY),
getDataMate(request),
sign);
}
public String contentType(HttpServletRequest request) {
return request.getHeader("Content-Type");
}
protected String getDataMate(HttpServletRequest request) {
if (Strings.equalsIgnoreCase(request.getMethod(), "GET")) {// GET请求需要处理一下
return Lang.md5(Http.encode(request.getQueryString(), request.getCharacterEncoding()));
}
// 文件上传
if (isFileUpload(request)) {
try {
return Lang.md5(new ByteArrayInputStream(
getUrlEncodedParams(request).getBytes(request.getCharacterEncoding())));
}
catch (IOException | ServletException e) {
Logs.get().debug("不支持的编码!");
throw Lang.wrapThrow(e);
}
}
try {
StringBuilder info = Streams.read(new InputStreamReader(request.getInputStream()));
if (info.length() == 0) {
return Lang.md5(
SignerHelper.paramMapAsUrlString(request.getParameterMap(), request.getCharacterEncoding()));
}
return Lang.md5(info);
}
catch (IOException e) {
throw Lang.wrapThrow(e);
}
}
public String getUrlEncodedParams(final HttpServletRequest request) throws IOException, ServletException {
final StringBuilder sb = new StringBuilder();
List parts = Lang.collection2list(request.getParts());
Collections.sort(parts, (part1, part2) -> part1.getName().compareTo(part2.getName()));
parts.stream().forEach(part -> {
String key = part.getName();
if (Strings.isBlank(part.getContentType())) {
// 参数
sb.append(Http.encode(key, request.getCharacterEncoding()))
.append('=')
.append(Http.encode(request.getParameter(key), request.getCharacterEncoding()))
.append('&');
} else {
// 文件
try {
sb.append(Http.encode(key, request.getCharacterEncoding()))
.append('=')
.append(Http.encode(Lang.md5(part.getInputStream()), request.getCharacterEncoding()))
.append('&');
}
catch (IOException e) {
throw Lang.wrapThrow(e);
}
}
});
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
return sb.toString();
}
private boolean isCommonFileUpload(HttpServletRequest request) {
return contentType(request) != null && contentType(request).startsWith("multipart/form-data");
}
/**
* @param request
* @return
*/
private boolean isFileUpload(HttpServletRequest request) {
return isCommonFileUpload(request) || isHtml5FileUpload(request);
}
private boolean isHtml5FileUpload(HttpServletRequest request) {
return contentType(request) != null && contentType(request).startsWith("application/octet-stream");
}
@Override
public KeyPairFetcher fetcher() {
return fetcher;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy