Spring Boot获取oss前端上传签名

获取上传签名代码

 /**
     * 获取签名
     * @return
     */
    public OssSignature getSignature(OSSClient ossClient,OssProperties ossProperties,String fileName) {
        /**
        * host的格式为 bucket .endpoint
        */
        String host = "";
        if (StringUtils.isBlank(ossProperties.getHost())){
             host = "http://" + ossProperties.getBucketName() + "." + ossProperties.getEndpoint();
        }else{
            host = ossProperties.getHost();
        }

        String dir = ossProperties.getDir();
        String str = "/";
        if (!dir.contains(str)){
            dir = dir + str;
        }

        OssSignature ossSignature = new OssSignature();
        try {
            long expireTime = 30;
            if(StringUtils.isNotBlank(ossProperties.getExpire())){
                expireTime = Long.parseLong(ossProperties.getExpire());
            }

            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.Exact, PolicyConditions.COND_KEY, fileName);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);



            ossSignature.setAccessKeyId(ossProperties.getAccessKeyId());
            ossSignature.setPolicy(encodedPolicy);
            ossSignature.setSignature(postSignature);
            ossSignature.setDir(fileName);
            ossSignature.setHost(host);
            ossSignature.setExpire(String.valueOf(expireEndTime / 1000));

            JSONObject jasonCallback = new JSONObject();
            jasonCallback.put("callbackUrl", ossProperties.getCallback());
            jasonCallback.put("callbackBody",
                    "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("utf-8"));

            ossSignature.setCallback(base64CallbackBody);

        } catch (Exception e) {
            log.error("获取签名失败:",e);
        }
        return ossSignature;
    }

因为上传回调需要外网访问本机的地址,所以可以不用写回调地址。前端判断响应状态码为200,则为成功。具体前端如何做参考前端上传代码

    /**
     * 获取public key
     *
     * @param url
     * @return
     */
    public String executeGet(String url) {
        BufferedReader in = null;

        String content = null;
        try {
            // 定义HttpClient
            @SuppressWarnings("resource")
            HttpClient client =  HttpClientBuilder.create().build();
            // 实例化HTTP方法
            HttpGet request = new HttpGet();
            request.setURI(new URI(url));
            HttpResponse response = client.execute(request);

            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer sb = new StringBuffer("");
            String line = "";
            String nL = System.getProperty("line.separator");
            while ((line = in.readLine()) != null) {
                sb.append(line + nL);
            }
            in.close();
            content = sb.toString();
            return content;
        } catch (Exception e) {
            log.error("获取public key:",e);
            return "";
        } finally {
            if (in != null) {
                try {
                    in.close();// 最后要关闭BufferedReader
                } catch (Exception e) {
                    log.error("关闭BufferedReader:",e);
                }
            }
        }
    }

    /**
     * 获取Post消息体
     *
     * @param is
     * @param contentLen
     * @return
     */
    public 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) {
                log.error("获取Post消息体失败:",e);
            }
        }
        return "";
    }

    /**
     * 验证上传回调的Request
     *
     * @param request
     * @param ossCallbackBody
     * @return
     * @throws NumberFormatException
     * @throws IOException
     */
    protected boolean verifyOSSCallbackRequest(HttpServletRequest request, String ossCallbackBody)
            throws NumberFormatException, IOException {
        boolean ret = false;
        String autorizationInput = new String(request.getHeader("Authorization"));
        if (StringUtils.isBlank(autorizationInput)){
            return false;
        }
        String pubKeyInput = request.getHeader("x-oss-pub-key-url");
        byte[] authorization = BinaryUtil.fromBase64String(autorizationInput);
        byte[] pubKey = BinaryUtil.fromBase64String(pubKeyInput);
        String pubKeyAddr = new String(pubKey);
        String http = "http://gosspublic.alicdn.com/";
        String https = "https://gosspublic.alicdn.com/";
        if (!pubKeyAddr.startsWith(http)
                && !pubKeyAddr.startsWith(https)) {
            System.out.println("pub key addr must be oss addrss");
            return false;
        }
        String retString = executeGet(pubKeyAddr);
        retString = retString.replace("-----BEGIN PUBLIC KEY-----", "");
        retString = retString.replace("-----END PUBLIC KEY-----", "");
        String queryString = request.getQueryString();
        String uri = request.getRequestURI();
        String decodeUri = java.net.URLDecoder.decode(uri, "UTF-8");
        String authStr = decodeUri;
        if (queryString != null && !"".equals(queryString)) {
            authStr += "?" + queryString;
        }
        authStr += "\n" + ossCallbackBody;
        ret = doCheck(authStr, authorization, retString);
        return ret;
    }

    /**
     * Post请求
     */
    public void callback(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String ossCallbackBody = getPostBody(request.getInputStream(),
                Integer.parseInt(request.getHeader("content-length")));
        boolean ret = verifyOSSCallbackRequest(request, ossCallbackBody);
        ///System.out.println("verify result : " + ret);
        if (ret) {
            response(request, response, "{\"Status\":\"OK\"}", HttpServletResponse.SC_OK);
        } else {
            response(request, response, "{\"Status\":\"verdify not ok\"}", HttpServletResponse.SC_BAD_REQUEST);
        }
    }

    /**
     * 验证RSA
     *
     * @param content
     * @param sign
     * @param publicKey
     * @return
     */
    public 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());
            boolean bverify = signature.verify(sign);
            return bverify;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * 服务器响应结果
     *
     * @param request
     * @param response
     * @param results
     * @param status
     * @throws IOException
     */
    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();
    }

    /**
     * 服务器响应结果
     */
    private void response(HttpServletRequest request, HttpServletResponse response, String results) throws IOException {
        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();
    }

使用说明

@SpringBootApplication
@EnableAliyunOss
@EnableSwagger2Doc
@RestController
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    
        @Autowired
        private OssProperties aliyunOssProperties;
        @Autowired
        private OSSClient ossClient;
    
        @ApiOperation("临时授权")
    @PostMapping("/getSignature")
    public OssSignature<String> getSignature(@RequestParam("orgFileName") String orgFileName) {

        String id = UuidUtils.createId();
        String str = "/";
        String dir = ossProperties.getDir();
        if (!dir.contains(str)){
            dir = dir+str;
        }
        String ext = orgFileName.substring(orgFileName.lastIndexOf("."));

        String newFileName = dir + id + ext;

        OssSignature<String> signature = new OssClientManager().getSignature(ossClient, ossProperties,newFileName);

        signature.setData(dir);
        return signature;
    }



    /**
     * Post请求
     */
    @GetMapping("/callback")
    public void callback(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        new OssClientManager().callback(request,response);
        }
    }

码云

posted @ 2020-06-14 19:22  一只奋斗的蜗牛  阅读(918)  评论(0编辑  收藏  举报