服务提供方和调用方同时用某个算法计算出一个token,比较时间来确定token是否有效。
1 import org.springframework.util.Assert;
2
3 import javax.crypto.Mac;
4 import javax.crypto.SecretKey;
5 import javax.crypto.spec.SecretKeySpec;
6 import java.util.Base64;
7 import java.util.Date;
8
9 /**
10 * @Author: pengbenlei
11 * @Date: 2020/8/27 11:24
12 * @Description: 接口授权码工具类
13 */
14 public class RequestApiAuthUtil {
15
16 static final Base64.Encoder encoder = Base64.getEncoder();
17
18 /**
19 * 请求授权码加密算法
20 *
21 * @param applicationCode 应用唯一码
22 * @param applicationKey 应用私钥
23 * @param timestamp 时间戳
24 */
25 public static String ecode(String applicationCode, String applicationKey, Long timestamp) {
26 String authCode = "";
27 try {
28 authCode = encoder.encodeToString(HmacSHA1Encrypt(applicationCode, applicationKey + timestamp.toString()));
29 } catch (Exception e) {
30 e.printStackTrace();
31 }
32 return authCode;
33 }
34
35 /**
36 * 请求授权码验证
37 */
38 public static Boolean authCodeVerification(String authCode, String applicationCode, String applicationKey, Long startTime) {
39 Long nowTime = new Date().getTime() / 1000;
40 long timeDifference = nowTime - startTime;
41 // 时间点相差的秒数
42 // 7200秒内视为有效
43 System.out.println("nowTime:" + nowTime + " startTime:" + startTime + " timeDifference" + timeDifference);
44 Assert.isTrue(!(timeDifference > 7200 || timeDifference < 0), "Error passing in timestamp");
45 //验证授权码
46 String correctCode = ecode(applicationCode, applicationKey, startTime);
47 Assert.isTrue(correctCode.equals(authCode), "Authorization code error, please check the algorithm or timestamp!");
48 return true;
49 }
50
51
52 private static final String MAC_NAME = "HmacSHA1";
53 private static final String ENCODING = "UTF-8";
54
55 public static byte[] HmacSHA1Encrypt(String encryptText, String encryptKey) throws Exception {
56 byte[] data = encryptKey.getBytes(ENCODING);
57 // 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
58 SecretKey secretKey = new SecretKeySpec(data, MAC_NAME);
59 // 生成一个指定 Mac 算法 的 Mac 对象
60 Mac mac = Mac.getInstance(MAC_NAME);
61 // 用给定密钥初始化 Mac 对象
62 mac.init(secretKey);
63
64 byte[] text = encryptText.getBytes(ENCODING);
65 // 完成 Mac 操作
66 return mac.doFinal(text);
67 }
68 }
1 import com.leenleda.common.config.LenledaConfig;
2 import com.leenleda.common.utils.RedisUtil;
3 import com.leenleda.wechat.utils.RequestApiAuthUtil;
4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.stereotype.Component;
6 import org.springframework.util.Assert;
7 import org.springframework.web.servlet.HandlerInterceptor;
8
9 import javax.annotation.Resource;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12
13 /**
14 * @Author: pengbenlei
15 * @Date: 2020/8/27 15:02
16 * @Description:
17 */
18 @Component
19 public class ApiAuthInterceptor implements HandlerInterceptor {
20
21
22 final
23 RedisUtil redisUtil;
24
25 public ApiAuthInterceptor(RedisUtil redisUtil) {
26 this.redisUtil = redisUtil;
27 }
28
29
30 @Override
31 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
32 // 验证token
33 String token = request.getHeader("token");
34 Assert.notNull(token, "token can not be empty!");
35 // 验证时间戳
36 Long timestamp = Long.valueOf(request.getHeader("timestamp"));
37 Assert.notNull(timestamp, "timestamp can not be empty!");
38 // 验证公钥
39 String publicKey = request.getHeader("public_key");
40 Assert.notNull(publicKey, "applicationCode can not be empty!");
41 // 验证token有效性
42 RequestApiAuthUtil.authCodeVerification(token, publicKey, privateKey(), timestamp);
43 return true;
44 }
45
46 }