AK/SK简介

AK(Access Key ID,用于标识用户)/SK(Secret Access Key,是用户用于加密认证的字符串和验证认证字符串的密钥,SK必须保密),主要用于对用户的调用行为进行鉴权和认证,相当于专用的用户名和密码

AK/SK认证流程

客户端根据双方协商好的规则算法生成Signature认证字符串,并将生成的Signature认证字符串设置到header中。当API网关/服务端接收到请求后,判断请求中是否包含Signature认证字符串。如果包含认证字符串,则执行下一步操作。
基于HTTP请求信息,使用与客户端相同的规则算法,生成Signature字符串并于与客户端提供的Signature字符串进行比对,如果内容不一致,则认为认证失败,拒绝该请求;如果内容一致,则表示认证成功,系统将按照客户端的请求内容进行操作。

客户端:
    构建http请求(包含 access key);
    使用请求内容和 使用secret access key计算的签名(signature);
    发送请求到服务端。
服务端:
    根据发送的access key 查找数据库获得对应的secret-key;
    使用一样的算法将请求内容和 secret-key一块儿计算签名(signature),和步骤2同样;
    对比用户发送的签名和服务端计算的签名,二者相同则认证经过,不然失败。

实现基本思路

  1. 客户端需要在认证服务器中预先设置(AK 或叫 app ID) 和 SK。
  2. 获取当前时间时间戳并生成请求唯一标识(随机码)
  3. 在调用API前,客户端需要将对 时间戳、请求标识、请求参数结合SK进行签名生成一个额外的sign字符串
  4. 将时间戳、请求标识、AK以及生成的sign字符串设置到请求header中
  5. 服务端收到客户端的请求后,先判断header中设置的四类认证数据是否存在。
  6. 根据header中的时间戳与当前时间比对判断是否该请求以过期,防止抓包后的恶意请求
  7. 根据header中的请求标识判断出该请求是否唯一(每次请求将唯一标识保存,待下次请求进来后进行比对判断。可设置保存时长)
  8. 根据AK获取客户端预先在认证服务器设置好的SK
  9. 将时间戳、请求标识、请求参数结合客户端预先设置好的SK使用与客户端相同的签名生成方式生成一个临时的sign字符串并与客户端请求中包含的sign字符串比较。
  10. 5、6、7、8、9这五步全部通过继续执行下一步操作,否则认证失败返回错误码

代码实现

基于上面的实现思路,大致写下代码,代码中加的有详细注释,逻辑就不一一解释了,写的比较简单。

拦截器懒得写了哈,我这就直接通过AOP 前置通知来实现认证信息的获取以及认证@Before("executePointcut()")public void before(JoinPoint joinPoint){HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();Object[] args = joinPoint.getArgs();JSONObject json = (JSONObject) args[args.length - 1];Map sortedMap = JsonToMap.sortParams(json);Long timeStamp = Long.parseLong(request.getHeader("TimeStamp"));String nonce = request.getHeader("nonce");String s = map.get(nonce);if (s!=null){log.error("重复的请求...");Asserts.fail("Repeat request");}map.put(nonce,nonce);//开启守护线程 清除请求唯一标识executorService.execute(new RemoveMapRunnable(nonce));String sign = request.getHeader("sign");if (timeStamp==null||timeStamp<1||StringUtils.isNotEmpty(nonce)||StringUtils.isNotEmpty(sign)){long endTime = System.currentTimeMillis();if (endTime-timeStamp > l){log.error("请求过期失效..");Asserts.fail("Request expired");}}else{log.error("认证参数缺失..");Asserts.fail("Missing authentication parameters");}if(!SignUtil.checkReqInfo(timeStamp, nonce, sign, sortedMap)){log.error("认证失败,sign={}",sign);Asserts.fail("Authentication failed");}log.info("认证成功...");}private class RemoveMapRunnable implements Runnable{private String nonce;public RemoveMapRunnable(String nonce){this.nonce = nonce;}@Overridepublic void run() {synchronized (this){try {Thread.sleep(l);map.remove(this.nonce);} catch (InterruptedException e) {e.printStackTrace();}}}}
/*** @Author lijl* @MethodName wrapperHeader* @Description 通过请求参数,包装请求header信息(含签名信息)* @Date 16:14 2021/11/11* @Version 1.0* @param reqParam* @return: {sign=02C89AD7CEC9C05831520015CD7C3413F1DE03822D2DA015A7B353B7E7F38E7D, nonce=6b10f2ee-aba6-4032-bc9f-ca82c76b30d1, TimeStamp=1636684729852}**/public static Map<String, Object> wrapperHeader(Map<String, Object> reqParam) {Long ts = System.currentTimeMillis();String nonce = UUID.randomUUID().toString();Map<String, Object> header = new HashMap<>();//进行接口调用时的时间戳,即当前时间戳(毫秒),服务端会校验时间戳,例如时间差超过30秒则认为请求无效,防止重复请求的攻击header.put("TimeStamp", ts);//每个请求提供一个唯一的标识符,服务器能够防止请求被多次使用header.put("nonce", nonce);//按签名算法获取signString sign = getSign(appSecret, ts, nonce, reqParam);header.put("sign", sign);return header;}/*** @Author lijl* @MethodName getSign* @Description 按签名算法获取sign* @Date 16:04 2021/11/11* @Version 1.0* @param appSecret* @param ts* @param nonce* @param reqParam* @return: java.lang.String**/private static String getSign(String appSecret, Long ts, String nonce, Map<String, Object> reqParam) {// 计算签名规则:sign = HMACSHA256("ts=1623388123195&noce=d50e301d-ee2c-446e-8f28-013f0fee09fb&appSecret=1ZLAzEgQHfBd19vSapdL8lxzA&1=2&1=2")// 1.请求参数key升序// 2.待加密字符串StringBuffer s = new StringBuffer();s.append("&ts=").append(ts).append("&noce=").append(nonce).append("&appSecret=").append(appSecret);reqParam.forEach((k, v) -> s.append("&").append(k).append("=").append(v));// 3.对待加密字符串进行加密(对字符串HMACSHA256处理,得到sign值)try {return HMACSHA256(s.toString());} catch (Exception e) {e.printStackTrace();}return null;}/*** @Author lijl* @MethodName checkReqInfo* @Description 验证请求是否有效* @Date 10:36 2021/11/12* @Version 1.0* @param ts* @param nonce* @param sign* @param reqParam* @return: 是否有效(方便测试我用Boolean,可根据业务需要,返回对应错误信息,不一定用Boolean)**/public static Boolean checkReqInfo(Long ts, String nonce, String sign,Map<String, Object> reqParam) {String srvSign = getSign(appSecret, ts, nonce, reqParam);// 目前能想到的安全验证就这些,或许大家还能想到其他验证,让接口更加安全return sign.equalsIgnoreCase(srvSign);}/*** @Author lijl* @MethodName HMACSHA256* @Description HMAC-SHA256算法* @Date 10:32 2021/11/12* @Version 1.0* @param data* @return: java.lang.String**/public static String HMACSHA256(String data) throws Exception {Mac sha256_HMAC = Mac.getInstance("HmacSHA256");SecretKeySpec secret_key = new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256");sha256_HMAC.init(secret_key);byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));StringBuilder sb = new StringBuilder();for (byte item : array) {sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));}return sb.toString().toUpperCase();}public static void main(String[] args) {Map<String, Object> reqParam = new HashMap<String, Object>();reqParam.put("1", "2");reqParam.put("2", "1");//请求头(行sign值等信息)Map<String, Object> reqHeader = wrapperHeader(reqParam);System.out.println(reqHeader);// ==================客户端发起请求,参数param,并把header带入请求中// ============================服务器端,收到请求// 1.验证请求信息// 2处理业务逻辑// 3.返回数据到客户端long ts = (long) reqHeader.get("TimeStamp");String nonce = (String) reqHeader.get("nonce");String sign = (String) reqHeader.get("sign");Boolean valid = checkReqInfo(ts,nonce,sign,reqParam);if (valid){System.out.println("有效请求,继续处理...");}else {System.out.println("无效");}}

Restful API AK/SK认证相关推荐

  1. Golang中AK/SK认证的实现

    Golang实现AK/SK认证 一.AK/SK概述 1. 什么是AKSK 2. AK/SK认证过程 二.AK/SK认证例子 1. 设计ak/sk的请求参数 2. 数据库中保存sk 3. 客户端生成签名 ...

  2. 双方API交互:签名及验证-- (AK/SK)认证的实现

    接口交互提供一个开发的接口地址和接口文档, 知道了url,知道了参数怎么传,坏人就来了: 1.可以任意请求任意参数值,调用你的接口. 2.频繁请求.恶意攻击,让你一直处理接口对应的业务逻辑. 3.拦截 ...

  3. ak sk认证java demo_AK-SK鉴权

    插件名称类别 名称 描述 属性 服务插件 AK/SK 鉴权 gw-ak_sk_auth 用户鉴权 功能描述 配置自己的AK/SK,或是使用网关自动生成的AK/SK,完成认证. 客户端涉及的AK/SK签 ...

  4. RESTful API接口之认证和权限

    认证和权限的区别: 认证:对用户登录的身份进行校验. 权限:对登录验证通过的用户,能够访问的api和对api能取得的对应级别数据做限制 认证 可以在这直接复制setting文件 BasicAuthen ...

  5. ak和sk怎么认证 海康威视_公有云API的认证方式:AK/SK 简介

    1 公有云API的认证方式 一般有一夏几种认证方式: Token认证 AK/SK认证 RSA非对称加密方式 下面主要介绍AK/SK 1 AK/SK 1.1 AK/SK 原理 云主机需要通过使用Acce ...

  6. 深入探索REST(1):如何设计好的RESTful API?

    REST架构风格最初由Roy T. Fielding(HTTP/1.1协议专家组负责人)在其2000年的博士学位论文中提出.HTTP就是该架构风格的一个典型应用.从其诞生之日开始,它就因其可扩展性和简 ...

  7. 如何设计好的RESTful API?

    REST架构风格最初由Roy T. Fielding(HTTP/1.1协议专家组负责人)在其2000年的博士学位论文中提出.HTTP就是该架构风格的一个典型应用.从其诞生之日开始,它就因其可扩展性和简 ...

  8. 虚拟研讨会:如何设计好的RESTful API?

    http://www.infoq.com/cn/articles/how-to-design-a-good-restful-api/ REST架构风格最初由Roy T. Fielding(HTTP/1 ...

  9. 如何设计好的RESTful API之安全性

    转自http://www.searchsoa.com.cn/showcontent_75305.htm InfoQ:安全是恒久的话题,对于基于WSDL和SOAP的Web Service,我们有WS-S ...

最新文章

  1. LoadRunner Controller集合点策略灰色问题 解决
  2. 实例告诉你如何把 if-else 重构成高质量代码!
  3. Oracle同义词创建及其作用(转载)
  4. Codeforces Round #420 (Div. 2)
  5. 计算机研究生怎样提高英语水平,英语对计算机专业的重要性及如何提高英语水平...
  6. python -- 计算 平方、乘方、平方根_从零开始学习PYTHON3讲义(二)把Python当做计算器...
  7. centos7 部署和配置Mysql5
  8. SAP UI5 的控件Focus 相关处理逻辑
  9. android fragment界面滑动切换效果,Android App中使用ViewPager+Fragment实现滑动切换效果...
  10. Tensorflow笔记(基础): 图与会话,变量
  11. ionic判断android版本,$ionicplatform 判断是android还是ios?
  12. Linux系统管理(9)——系统状态监控命令top使用详解
  13. pku 1639 Picnic Planning 最小度限制生成树
  14. ServletContextAware、ServletRequestAware、ServletResponseAware、SessionAware
  15. linux远程桌面rdesktop,Linux下通过rdesktop连接Windows远程桌面
  16. excel表格怎么画斜线_怎么画出漂亮的Excel表格线?
  17. nothing else left on those streets
  18. Transformer-M:一个能理解2D和3D分子的Transformer
  19. 2022CTFSHOW菜狗杯部分MISC(二)
  20. 编译器对源代码的编译过程

热门文章

  1. python爬虫爬取校花网视频
  2. 数值分析——数值积分(Newton-Cotes、复化求积、Gauss求积、正交多项式Gauss)
  3. 如何在MATLAB中输入希腊字母
  4. python 判断字符串是否是汉字,数字,英语或其他
  5. Leetcode-1027最长等差数列
  6. localdatetime 后一天_Java LocalDateTime获取前一天,—-JDK8新时间类的简单使用
  7. qpython如何安装库_qpython3如何安装库
  8. 深大数据库实验2之思考题之php前后台的编写
  9. WORD与DWORD
  10. 科技云报道:实战化时代,安全托管MSS更需“行业专家”