Ver Fonte

更改Authorization为AuthorizationToken,阿里云OSS图片服务签名回调

change há 4 anos atrás
pai
commit
bf6c049bec

+ 53 - 0
zhongzheng-admin/src/main/java/com/zhongzheng/controller/alioss/OssController.java

@@ -0,0 +1,53 @@
+package com.zhongzheng.controller.alioss;
+
+
+import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.modules.alioss.service.OssService;
+import com.zhongzheng.modules.alioss.vo.ResultBean;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+/**
+ * 阿里OSS
+ *
+ * @author change
+ * @date 2021-05-17
+ */
+@Api(value = "阿里OSS上传文件控制器", tags = {"阿里OSS上传文件"})
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@RestController
+@RequestMapping("/aliyun/oss")
+public class OssController {
+
+    private static Logger log = LoggerFactory.getLogger(OssController.class);
+
+    private final OssService ossService;
+
+    /**
+     * policy
+     */
+    @ApiOperation("policy获得")
+    @GetMapping("/policy")
+    public AjaxResult<ResultBean> policy() {
+        ResultBean result = ossService.getPolicy();
+        log.info("服务端生成签名:{}",result);
+        return AjaxResult.success(result);
+    }
+
+    @ApiOperation("回调")
+    @PostMapping("/callback")
+    public ResultBean callback(@RequestBody Map<String, Object> map) {
+        ResultBean ossCallbackResult = ossService.callback(map);
+        log.info("oss成功的回调:{}",ossCallbackResult);
+        return ossCallbackResult;
+    }
+
+}

+ 20 - 0
zhongzheng-admin/src/main/java/com/zhongzheng/core/config/OssConfig.java

@@ -0,0 +1,20 @@
+package com.zhongzheng.core.config;
+
+import com.aliyun.oss.OSSClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class OssConfig {
+    @Value("${aliyun.oss.endpoint}")
+    private String ALIYUN_OSS_ENDPOINT;
+    @Value("${aliyun.oss.accessKeyId}")
+    private String ALIYUN_OSS_ACCESSKEYID;
+    @Value("${aliyun.oss.accessKeySecret}")
+    private String ALIYUN_OSS_ACCESSKEYSECRET;
+    @Bean
+    public OSSClient ossClient(){
+        return new OSSClient(ALIYUN_OSS_ENDPOINT,ALIYUN_OSS_ACCESSKEYID,ALIYUN_OSS_ACCESSKEYSECRET);
+    }
+}

+ 3 - 3
zhongzheng-admin/src/main/java/com/zhongzheng/core/config/SwaggerConfig.java

@@ -80,12 +80,12 @@ public class SwaggerConfig
     }
 
     /**
-     * 安全模式,这里指定token通过Authorization头请求头传递
+     * 安全模式,这里指定token通过AuthorizationToken头请求头传递
      */
     private List<ApiKey> securitySchemes()
     {
         List<ApiKey> apiKeyList = new ArrayList<ApiKey>();
-    //    apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));//强制全局参数
+    //    apiKeyList.add(new ApiKey("AuthorizationToken", "AuthorizationToken", "header"));//强制全局参数
         return apiKeyList;
     }
 
@@ -112,7 +112,7 @@ public class SwaggerConfig
         AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
         authorizationScopes[0] = authorizationScope;
         List<SecurityReference> securityReferences = new ArrayList<>();
-        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
+        securityReferences.add(new SecurityReference("AuthorizationToken", authorizationScopes));
         return securityReferences;
     }
 

+ 12 - 0
zhongzheng-admin/src/main/resources/application-dev.yml

@@ -77,3 +77,15 @@ spring:
                 max-active: 8
                 # #连接池最大阻塞等待时间(使用负值表示没有限制)
                 max-wait: -1ms
+aliyun:
+    oss:
+        endpoint: testzhongzheng.oss-cn-beijing.aliyuncs.com # oss对外服务的访问域名
+        accessKeyId: LTAI4FeyKgAY6A1dPfmsaMCg  # 访问身份验证中用到用户标识
+        accessKeySecret: ZrLRsqLw2NzHCIszEzwZWs55eVHYwM # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
+        bucketName: testzhongzheng # oss的存储空间
+        policy:
+            expire: 30 # 签名有效期(S)
+        maxSize: 10 # 上传文件大小(M)
+        callback: http://p5q3vfni.dongtaiyuming.net/aliyun/oss/callback # 文件上传成功后的回调地址
+        dir:
+            prefix: oss/images/ # 上传文件夹路径前缀 `

+ 13 - 1
zhongzheng-admin/src/main/resources/application-prod.yml

@@ -76,4 +76,16 @@ spring:
                 # 连接池的最大数据库连接数
                 max-active: 8
                 # #连接池最大阻塞等待时间(使用负值表示没有限制)
-                max-wait: -1ms
+                max-wait: -1ms
+aliyun:
+    oss:
+        endpoint: testzhongzheng.oss-cn-beijing.aliyuncs.com # oss对外服务的访问域名
+        accessKeyId: LTAI4FeyKgAY6A1dPfmsaMCg  # 访问身份验证中用到用户标识
+        accessKeySecret: ZrLRsqLw2NzHCIszEzwZWs55eVHYwM # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
+        bucketName: testzhongzheng # oss的存储空间
+        policy:
+            expire: 30 # 签名有效期(S)
+        maxSize: 10 # 上传文件大小(M)
+        callback: http://p5q3vfni.dongtaiyuming.net/aliyun/oss/callback # 文件上传成功后的回调地址
+        dir:
+            prefix: oss/images/ # 上传文件夹路径前缀 `

+ 1 - 1
zhongzheng-admin/src/main/resources/application.yml

@@ -108,7 +108,7 @@ management:
 # token配置
 token:
     # 令牌自定义标识
-    header: Authorization
+    header: AuthorizationToken
     # 令牌密钥
     secret: abcdefghijklmnopqrstuvwxyz
     # 令牌有效期(默认30分钟)

+ 3 - 3
zhongzheng-api/src/main/java/com/zhongzheng/core/config/SwaggerConfig.java

@@ -68,12 +68,12 @@ public class SwaggerConfig
     }
 
     /**
-     * 安全模式,这里指定token通过Authorization头请求头传递
+     * 安全模式,这里指定token通过AuthorizationToken头请求头传递
      */
     private List<ApiKey> securitySchemes()
     {
         List<ApiKey> apiKeyList = new ArrayList<ApiKey>();
-        apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
+        apiKeyList.add(new ApiKey("AuthorizationToken", "AuthorizationToken", "header"));
         return apiKeyList;
     }
 
@@ -100,7 +100,7 @@ public class SwaggerConfig
         AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
         authorizationScopes[0] = authorizationScope;
         List<SecurityReference> securityReferences = new ArrayList<>();
-        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
+        securityReferences.add(new SecurityReference("AuthorizationToken", authorizationScopes));
         return securityReferences;
     }
 

+ 1 - 1
zhongzheng-api/src/main/resources/application.yml

@@ -108,7 +108,7 @@ management:
 # token配置
 token:
     # 令牌自定义标识
-    header: Authorization
+    header: AuthorizationToken
     # 令牌密钥
     secret: abcdefghijklmnopqrstuvwxyz
     # 令牌有效期(默认30分钟)

+ 8 - 0
zhongzheng-common/pom.xml

@@ -59,6 +59,14 @@
             <artifactId>jackson-databind</artifactId>
         </dependency>
 
+        <!-- OSS SDK 相关依赖 -->
+        <!-- OSS SDK 相关依赖 -->
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>2.5.0</version>
+        </dependency>
+
         <!-- 阿里JSON解析器 -->
         <dependency>
             <groupId>com.alibaba</groupId>

+ 1 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/config/SecurityConfig.java

@@ -102,6 +102,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .authorizeRequests()
                 // 对于登录login 验证码captchaImage 允许匿名访问
                 .antMatchers("/login", "/captchaImage").anonymous()
+                .antMatchers("/aliyun/oss/policy", "/aliyun/oss/callback").anonymous()
                 .antMatchers(
                         HttpMethod.GET,
                         "/*.html",

+ 25 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/alioss/bo/OssCallbackParam.java

@@ -0,0 +1,25 @@
+package com.zhongzheng.modules.alioss.bo;
+
+import lombok.Data;
+
+/**
+ * oss上传成功后的回调参数
+ */
+@Data
+public class OssCallbackParam {
+    /**
+     *
+        请求的回调地址
+     */
+    private String callbackUrl;
+    /**
+     *
+        回调是传入request中的参数
+     */
+    private String callbackBody;
+    /**
+        回调时传入参数的格式,比如表单提交形式
+    */
+    private String callbackBodyType;
+
+}

+ 14 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/alioss/service/OssService.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.modules.alioss.service;
+
+
+
+import com.zhongzheng.modules.alioss.vo.ResultBean;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+public interface OssService {
+    ResultBean getPolicy();
+
+    ResultBean callback(Map<String, Object> map);
+}

+ 114 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/alioss/service/impl/OssServiceImpl.java

@@ -0,0 +1,114 @@
+package com.zhongzheng.modules.alioss.service.impl;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+
+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.zhongzheng.common.constant.Constants;
+import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.modules.alioss.bo.OssCallbackParam;
+import com.zhongzheng.modules.alioss.service.OssService;
+import com.zhongzheng.modules.alioss.vo.ResultBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Map;
+import java.util.Random;
+
+@Service
+public class OssServiceImpl implements OssService {
+    private static final Logger LOGGER = LoggerFactory.getLogger(OssServiceImpl.class);
+    @Value("${aliyun.oss.policy.expire}")
+    private int ALIYUN_OSS_EXPIRE;
+    @Value("${aliyun.oss.maxSize}")
+    private int ALIYUN_OSS_MAX_SIZE;
+    @Value("${aliyun.oss.callback}")
+    private String ALIYUN_OSS_CALLBACK;
+    @Value("${aliyun.oss.bucketName}")
+    private String ALIYUN_OSS_BUCKET_NAME;
+    @Value("${aliyun.oss.endpoint}")
+    private String ALIYUN_OSS_ENDPOINT;
+    @Value("${aliyun.oss.dir.prefix}")
+    private String ALIYUN_OSS_DIR_PREFIX;
+
+    @Autowired
+    private OSSClient ossClient;
+    @Override
+    public ResultBean getPolicy() {
+        JSONObject resultBean = new JSONObject();
+        // 存储目录
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        String dir = ALIYUN_OSS_DIR_PREFIX+sdf.format(new Date())+"/"+ this.generateRandomFilename();
+        // 签名有效期
+        long expireEndTime = System.currentTimeMillis() + ALIYUN_OSS_EXPIRE * 1000;
+        Date expiration = new Date(expireEndTime);
+        // 文件大小
+        long maxSize = ALIYUN_OSS_MAX_SIZE * 1024 * 1024;
+        // 回调
+        OssCallbackParam callback = new OssCallbackParam();
+        callback.setCallbackUrl(ALIYUN_OSS_CALLBACK);
+        callback.setCallbackBody("{\"filename\":${object},\"size\":${size},\"mimeType\":${mimeType},\"height\":${imageInfo.height},\"width\":${imageInfo.width}}");
+        callback.setCallbackBodyType("application/json");
+        // 提交节点
+        String action = "https://" + ALIYUN_OSS_ENDPOINT;
+        try {
+            PolicyConditions policyConds = new PolicyConditions();
+            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);
+            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
+            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
+            byte[] binaryData = postPolicy.getBytes("utf-8");
+            String policy = BinaryUtil.toBase64String(binaryData);
+            String signature = ossClient.calculatePostSignature(postPolicy);
+            String callbackData = BinaryUtil.toBase64String(JSONUtil.parse(callback).toString().getBytes("utf-8"));
+            resultBean.set("accessid",ossClient.getCredentialsProvider().getCredentials().getAccessKeyId()).set("policy",policy).set("signature",signature)
+            .set("dir",dir).set("expire",String.valueOf(expireEndTime / 1000)).set("callback",callbackData).set("host",action);
+            // 返回结果
+        } catch (Exception e) {
+            LOGGER.error("签名生成失败", e);
+            throw new CustomException("签名生成失败");
+        }
+
+        return new ResultBean(resultBean);
+    }
+
+
+    public String generateRandomFilename() {
+        String RandomFilename = "";
+        //生成随机数
+        Random rand = new Random();
+        int random = rand.nextInt();
+
+        Calendar calCurrent = Calendar.getInstance();
+        int intDay = calCurrent.get(Calendar.DATE);
+        int intMonth = calCurrent.get(Calendar.MONTH) + 1;
+        int intYear = calCurrent.get(Calendar.YEAR);
+        String now = String.valueOf(intYear) + "_" + String.valueOf(intMonth) + "_" +
+                String.valueOf(intDay) + "_";
+
+        RandomFilename = now + String.valueOf(random > 0 ? random : (-1) * random);
+
+        return RandomFilename;
+
+    }
+
+    @Override
+    public ResultBean callback(Map<String, Object> map) {
+        JSONObject resultBean = new JSONObject();
+        String filename = map.get("filename").toString();
+        filename = "https://".concat(ALIYUN_OSS_ENDPOINT).concat("/").concat(filename);
+        resultBean.set("filename",filename).set("size",map.get("size").toString()).set("mimeType",map.get("mimeType").toString())
+        .set("width",map.get("width").toString()).set("height",map.get("height").toString());
+       return new ResultBean(resultBean);
+    }
+}

+ 21 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/alioss/vo/ResultBean.java

@@ -0,0 +1,21 @@
+package com.zhongzheng.modules.alioss.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+@Data
+@ApiModel("【oss】视图对象")
+public class ResultBean {
+
+
+    private Object resultContent;
+
+
+
+    public ResultBean(Object resultContent){
+        this.resultContent = resultContent;
+    }
+
+
+
+}