vod普通加密
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -185,7 +185,11 @@
|
||||
<artifactId>poi-ooxml-schemas</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>sts20150401</artifactId>
|
||||
<version>1.1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aspose.words</groupId>
|
||||
<artifactId>aspose-words</artifactId>
|
||||
|
||||
167
src/main/java/com/peanut/common/utils/PlayToken.java
Normal file
167
src/main/java/com/peanut/common/utils/PlayToken.java
Normal file
@@ -0,0 +1,167 @@
|
||||
package com.peanut.common.utils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
import com.peanut.modules.common.dao.VodAesTokenDao;
|
||||
import com.peanut.modules.common.entity.VodAesTokenEntity;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class PlayToken {
|
||||
|
||||
@Autowired
|
||||
private VodAesTokenDao vodAesTokenDao;
|
||||
|
||||
//非AES生成方式,无需以下参数
|
||||
private static String ENCRYPT_KEY = "abcdefgh#$&!mnopqrstuvwxyz123456"; //加密Key,为用户自定义的字符串,长度为16、24或32位
|
||||
private static String INIT_VECTOR = "ABCDEFGHIJKLMNOP"; //加密偏移量,为用户自定义字符串,长度为16位,不能含有特殊字符
|
||||
|
||||
// public static void main(String[] args) throws Exception {
|
||||
//
|
||||
// String serviceId = "12";
|
||||
// PlayToken playToken = new PlayToken();
|
||||
// String aesToken = playToken.generateToken(serviceId);
|
||||
// //System.out.println("aesToken " + aesToken);
|
||||
// //System.out.println(playToken.validateToken(aesToken)); //验证解密部分
|
||||
//
|
||||
// }
|
||||
/**
|
||||
* 根据传递的参数生成令牌
|
||||
* 说明:
|
||||
* 1、参数可以是业务方的用户ID、播放终端类型等信息
|
||||
* 2、调用令牌接口时生成令牌Token
|
||||
* @return
|
||||
*/
|
||||
public String generateToken() throws Exception {
|
||||
// if (null == args || args.length <= 0) {
|
||||
// return null;
|
||||
// }
|
||||
// String base = StringUtils.join(Arrays.asList(args), "_");
|
||||
int bas = (int)(Math.random()*90+10);
|
||||
String base = String.valueOf(bas);
|
||||
//设置60S后,该token过期,过期时间可以自行调整
|
||||
long expire = System.currentTimeMillis() + 60000L;
|
||||
base += "_" + expire; //自定义字符串,base的长度为16位字符(此例中,时间戳占13位,下划线(_)占1位,则还需传入2位字符。实际配置时也可按需全部更改,最终保证base为16、24或32位字符串即可。)
|
||||
//生成token
|
||||
String token = encrypt(base, ENCRYPT_KEY); //arg1为要加密的自定义字符串,arg2为加密Key
|
||||
//保存token,用于解密时校验token的有效性,例如:过期时间、token的使用次数
|
||||
saveToken(token);
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证token的有效性
|
||||
* 说明:
|
||||
* 1、解密接口在返回播放密钥前,需要先校验Token的合法性和有效性
|
||||
* 2、强烈建议同时校验Token的过期时间以及Token的有效使用次数
|
||||
* @param token
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public boolean validateToken(String token) throws Exception {
|
||||
if (null == token || "".equals(token)) {
|
||||
return false;
|
||||
}
|
||||
String base = decrypt(token,ENCRYPT_KEY); //arg1为解密字符串,arg2为解密Key
|
||||
//先校验token的有效时间
|
||||
Long expireTime = Long.valueOf(base.substring(base.lastIndexOf("_") + 1));
|
||||
// System.out.println("时间校验:" + expireTime);
|
||||
if (System.currentTimeMillis() > expireTime) {
|
||||
return false;
|
||||
}
|
||||
//从DB获取token信息,判断token的有效性,业务方可自行实现
|
||||
VodAesTokenEntity dbToken = getToken(token);
|
||||
//判断是否已经使用过该token
|
||||
if (dbToken == null || dbToken.getUseCount() > 0) {
|
||||
return false;
|
||||
}
|
||||
dbToken.setUseCount(1);
|
||||
vodAesTokenDao.updateById(dbToken);
|
||||
//获取到业务属性信息,用于校验
|
||||
String businessInfo = base.substring(0, base.lastIndexOf("_"));
|
||||
String[] items = businessInfo.split("_");
|
||||
//校验业务信息的合法性,业务方实现
|
||||
return validateInfo(items);
|
||||
}
|
||||
/**
|
||||
* 保存Token到DB
|
||||
* 业务方自行实现
|
||||
*
|
||||
* @param token
|
||||
*/
|
||||
public void saveToken(String token) {
|
||||
VodAesTokenEntity vodAesTokenEntity = new VodAesTokenEntity();
|
||||
vodAesTokenEntity.setToken(token);
|
||||
vodAesTokenDao.insert(vodAesTokenEntity);
|
||||
//TODO 存储Token
|
||||
}
|
||||
/**
|
||||
* 查询Token
|
||||
* 业务方自行实现
|
||||
*
|
||||
* @param token
|
||||
*/
|
||||
public VodAesTokenEntity getToken(String token) {
|
||||
List<VodAesTokenEntity> vodAesTokenEntities = vodAesTokenDao.selectList(new LambdaQueryWrapper<VodAesTokenEntity>().eq(VodAesTokenEntity::getToken, token));
|
||||
if(vodAesTokenEntities.size()!=1){
|
||||
return null;
|
||||
}else{
|
||||
return vodAesTokenEntities.get(0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 校验业务信息的有效性,业务方可自行实现
|
||||
*
|
||||
* @param infos
|
||||
* @return
|
||||
*/
|
||||
private boolean validateInfo(String... infos) {
|
||||
//TODO 校验信息的有效性,例如UID是否有效等
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* AES加密生成Token
|
||||
*
|
||||
* @param encryptStr 要加密的字符串
|
||||
* @param encryptKey 加密Key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public String encrypt(String encryptStr, String encryptKey) throws Exception {
|
||||
IvParameterSpec e = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(encryptKey.getBytes("UTF-8"), "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, e);
|
||||
byte[] encrypted = cipher.doFinal(encryptStr.getBytes());
|
||||
return Base64.encodeBase64String(encrypted);
|
||||
}
|
||||
/**
|
||||
* AES解密token
|
||||
*
|
||||
* @param encryptStr 解密字符串
|
||||
* @param decryptKey 解密Key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public String decrypt(String encryptStr, String decryptKey) throws Exception {
|
||||
|
||||
IvParameterSpec e = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(decryptKey.getBytes("UTF-8"), "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
|
||||
cipher.init(Cipher.DECRYPT_MODE, skeySpec, e);
|
||||
|
||||
byte[] encryptByte = Base64.decodeBase64(encryptStr);
|
||||
byte[] decryptByte = cipher.doFinal(encryptByte);
|
||||
return new String(decryptByte);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,13 @@ import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.aliyun.vod20170321.Client;
|
||||
import com.aliyun.vod20170321.models.GetVideoPlayAuthRequest;
|
||||
import com.aliyun.vod20170321.models.GetVideoPlayAuthResponse;
|
||||
import com.aliyuncs.profile.DefaultProfile;
|
||||
import com.aliyuncs.DefaultAcsClient;
|
||||
import com.aliyuncs.exceptions.ClientException;
|
||||
import com.aliyuncs.http.MethodType;
|
||||
import com.aliyuncs.profile.IClientProfile;
|
||||
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
|
||||
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
|
||||
//import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||
//import org.bytedeco.javacv.FrameGrabber;
|
||||
|
||||
@@ -59,4 +66,53 @@ public class SpdbUtil {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static AssumeRoleResponse assumeRole() throws ClientException {
|
||||
try {
|
||||
|
||||
String accessKeyId = "LTAI5tC9d38msYxw6RSEwJJR";
|
||||
|
||||
String accessKeySecret = "njJxkvrwBmbMfGyhAFeyjthodnwt58";
|
||||
|
||||
String roleArn = "acs:ram::1604740137891907:role/vodrole";
|
||||
|
||||
String roleSessionName = "testsession";
|
||||
|
||||
String policy = "{\n" +
|
||||
" \"Version\": \"1\",\n" +
|
||||
" \"Statement\": [\n" +
|
||||
" {\n" +
|
||||
" \"Action\": \"vod:*\",\n" +
|
||||
" \"Resource\": \"*\",\n" +
|
||||
" \"Effect\": \"Allow\"\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
"}";
|
||||
//构造default profile(参数留空,无需添加Region ID)
|
||||
/*
|
||||
说明:当设置SysEndpoint为sts.aliyuncs.com时,regionId可填可不填;反之,regionId必填,根据使用的服务区域填写,例如:cn-shanghai
|
||||
详情参考STS各地域的Endpoint。
|
||||
*/
|
||||
IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret);
|
||||
//用profile构造client
|
||||
DefaultAcsClient client = new DefaultAcsClient(profile);
|
||||
// 创建一个 AssumeRoleRequest 并设置请求参数
|
||||
final AssumeRoleRequest request = new AssumeRoleRequest();
|
||||
// request.setSysEndpoint("sts.aliyuncs.com");
|
||||
// request.setSysMethod(MethodType.POST);
|
||||
request.setRoleArn(roleArn);
|
||||
request.setRoleSessionName(roleSessionName);
|
||||
request.setPolicy(policy);
|
||||
request.setRegionId("cn-shanghai");
|
||||
// 发起请求,并得到response
|
||||
final AssumeRoleResponse response = client.getAcsResponse(request);
|
||||
return response;
|
||||
} catch (ClientException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.peanut.modules.common.dao;
|
||||
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.peanut.modules.common.entity.VodAesTokenEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface VodAesTokenDao extends MPJBaseMapper<VodAesTokenEntity> {
|
||||
}
|
||||
@@ -36,4 +36,6 @@ public class CourseCatalogueChapterVideoEntity {
|
||||
private UserCourseVideoPositionEntity userCourseVideoPositionEntity;
|
||||
@TableField(exist = false)
|
||||
private String videoUrl;
|
||||
@TableField(exist = false)
|
||||
private String Mp4Url;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.peanut.modules.common.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@TableName("vod_aes_token")
|
||||
public class VodAesTokenEntity {
|
||||
|
||||
@TableId
|
||||
private Integer id;
|
||||
|
||||
private String token;
|
||||
|
||||
private Integer useCount;
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.peanut.modules.sociology.controller;
|
||||
|
||||
import com.aliyun.vod20170321.models.*;
|
||||
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.peanut.common.utils.PlayToken;
|
||||
import com.peanut.common.utils.R;
|
||||
import com.peanut.common.utils.ShiroUtils;
|
||||
import com.peanut.common.utils.SpdbUtil;
|
||||
@@ -14,6 +16,7 @@ import com.peanut.modules.master.service.SysCourseDirectService;
|
||||
import com.peanut.modules.sociology.service.CourseCatalogueChapterService;
|
||||
import com.peanut.modules.sociology.service.CourseService;
|
||||
import com.peanut.modules.sociology.service.CourseSociologyService;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@@ -42,6 +45,8 @@ public class CourseController {
|
||||
|
||||
@Autowired
|
||||
private UserCourseStudyingDao userCourseStudyingDao;
|
||||
@Autowired
|
||||
private PlayToken playToken;
|
||||
|
||||
/**
|
||||
* 获取用户最近学习课程列表
|
||||
@@ -193,6 +198,22 @@ public class CourseController {
|
||||
return courseCatalogueChapterVideoService.checkVideo(video);
|
||||
}
|
||||
|
||||
@RequestMapping("/mytt")
|
||||
public R mytt() throws Exception {
|
||||
String s = playToken.generateToken();
|
||||
System.out.println(s);
|
||||
boolean b = playToken.validateToken(s);
|
||||
System.out.println(b);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@RequestMapping("/ttt")
|
||||
@SneakyThrows
|
||||
public R ttt(){
|
||||
AssumeRoleResponse assumeRoleResponse = SpdbUtil.assumeRole();
|
||||
return R.ok().put("result",assumeRoleResponse);
|
||||
}
|
||||
|
||||
@RequestMapping("/getMyCourse")
|
||||
public R getMyCourse(@RequestBody Map<String,Integer> map){
|
||||
List courses = courseService.getMyCourse(map.get("type"));
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.peanut.modules.sys.controller;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/vodAli")
|
||||
public class VodAliController {
|
||||
|
||||
|
||||
@RequestMapping("/vodAliVideoRe")
|
||||
public void vodAliVideoRe(@RequestBody Map<String,Object> map){
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user