版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_15071263/article/details/84653702
OSS 前端直传的后端签名过程
package com.zyfycs.college.plugin.alibaba.oss;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.google.common.collect.Maps;
import com.zyfycs.college.config.plugin.alibaba.oss.OSSConfig;
import com.zyfycs.college.util.UUID;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.Map;
/**
* @author Created by 谭健 on 2018/11/30. 星期五. 10:59.
* © All Rights Reserved.
*/
@Api(tags = "oss 直传插件")
@RequestMapping("/open")
@RestController
public class OSSDirectUploadPlugin {
@Autowired
private RestTemplate restTemplate;
@ApiOperation("用户发布一个感悟的图片上传回调")
@PostMapping("/uploadImgCallback")
public void uploadImgCallback(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String ossCallbackBody = getpostbody(request.getInputStream(),
Integer.parseInt(request.getHeader("content-length")));
boolean ret = verifyosscallbackrequest(request, ossCallbackBody);
if (ret) {
response(request, response, "{\"Status\":\"OK\"}", HttpServletResponse.SC_OK);
} else {
response(request, response, "{\"Status\":\"verdify not ok\"}", HttpServletResponse.SC_BAD_REQUEST);
}
}
@ApiOperation("用户获取OSS直传签名")
@GetMapping("/getOSSUploadSign")
public void getOSSUploadSign(HttpServletRequest request, HttpServletResponse response) {
OSSClient client = new OSSClient(OSSConfig.END_POINT, OSSConfig.ACCESS_KEY_ID, OSSConfig.ACCESS_KEY_SECRET);
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, OSSConfig.DIR);
String postPolicy = client.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = client.calculatePostSignature(postPolicy);
Map<String, String> respMap = Maps.newLinkedHashMap();
respMap.put("accessid", OSSConfig.ACCESS_KEY_ID);
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", OSSConfig.DIR);
respMap.put("host", OSSConfig.HOST);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
JSONObject jasonCallback = new JSONObject();
String filename = UUID.randomUUID();
jasonCallback.put("callbackUrl", OSSConfig.CALL_BACK_URL);
jasonCallback.put("callbackBody", "filename=" + filename + "_${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
respMap.put("callback", base64CallbackBody);
String json = JSON.toJSONString(respMap);
response(request, response, json);
} catch (Exception e) {
e.printStackTrace();
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
private void response(HttpServletRequest request, HttpServletResponse response, String results) throws IOException {
System.out.println(results);
String callbackFunName = request.getParameter("callback");
if (callbackFunName == null || "".equalsIgnoreCase(callbackFunName)) {
response.getWriter().println(results);
} else {
response.getWriter().println(callbackFunName + "( " + results + " )");
}
response.setStatus(HttpServletResponse.SC_OK);
response.flushBuffer();
}
private String getpostbody(InputStream is, int contentLen) {
if (contentLen > 0) {
int readLen = 0;
int readLengthThisTime = 0;
byte[] message = new byte[contentLen];
try {
while (readLen != contentLen) {
readLengthThisTime = is.read(message, readLen, contentLen - readLen);
// Should not happen.
if (readLengthThisTime == -1) {
break;
}
readLen += readLengthThisTime;
}
return new String(message);
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
}
private boolean verifyosscallbackrequest(HttpServletRequest request, String ossCallbackBody)
throws NumberFormatException, IOException {
boolean ret = false;
String autorizationInput = request.getHeader("Authorization");
String pubKeyInput = request.getHeader("x-oss-pub-key-url");
byte[] authorization = BinaryUtil.fromBase64String(autorizationInput);
byte[] pubKey = BinaryUtil.fromBase64String(pubKeyInput);
String pubKeyAddr = new String(pubKey);
if (!pubKeyAddr.startsWith("http://gosspublic.alicdn.com/")
&& !pubKeyAddr.startsWith("https://gosspublic.alicdn.com/")) {
System.out.println("pub key addr must be oss addrss");
return false;
}
String retString = restTemplate.getForEntity(pubKeyAddr, String.class).getBody();
retString = retString.replace("-----BEGIN PUBLIC KEY-----", "");
retString = retString.replace("-----END PUBLIC KEY-----", "");
String queryString = request.getQueryString();
String uri = request.getRequestURI();
String authStr = java.net.URLDecoder.decode(uri, "UTF-8");
if (queryString != null && !"".equals(queryString)) {
authStr += "?" + queryString;
}
authStr += "\n" + ossCallbackBody;
ret = doCheck(authStr, authorization, retString);
return ret;
}
private static boolean doCheck(String content, byte[] sign, String publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = BinaryUtil.fromBase64String(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
java.security.Signature signature = java.security.Signature.getInstance("MD5withRSA");
signature.initVerify(pubKey);
signature.update(content.getBytes());
return signature.verify(sign);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private void response(HttpServletRequest request, HttpServletResponse response, String results, int status)
throws IOException {
String callbackFunName = request.getParameter("callback");
response.addHeader("Content-Length", String.valueOf(results.length()));
if (callbackFunName == null || "".equalsIgnoreCase(callbackFunName)) {
response.getWriter().println(results);
} else {
response.getWriter().println(callbackFunName + "( " + results + " )");
}
response.setStatus(status);
response.flushBuffer();
}
}