Soul網關學習Sign插件

Soul網關學習Sign插件

做者: "唐甜"spring

介紹

sign插件用來對請求進行簽名認證的插件markdown

AK / SK介紹

AK / SK(訪問密鑰ID /祕密訪問密鑰)即訪問密鑰,包含訪問密鑰ID(AK)和祕密訪問密鑰(SK)兩部分,主要用於對用戶的調用行爲進行鑑權和認證。app

插件使用-以(/ dubbo / findAll)爲例

在SoulBootstrap的pom.xml文件中添加 sign 的支持

<!-- soul sign plugin start-->
  <dependency>
      <groupId>org.dromara</groupId>
      <artifactId>soul-spring-boot-starter-plugin-sign</artifactId>
     <version>${last.version}</version>
  </dependency>
  <!-- soul sign plugin end-->

複製代碼

新增appKey,secretKey

image.png image.png image.png image.png

配置選擇器和規則器

添加選擇器 image.png 添加規則器 image.pngide

增長獲取鑑權服務

在本身服務中增長一個對外訪問的方法spring-boot

@GetMapping("/authUrl")
    public String authUrl() {
        Map<String, String> map = Maps.newHashMapWithExpectedSize(2);
        //timestamp爲毫秒數的字符串形式 String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli())
        String timetamp = String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli()) ;
        System.out.println(timetamp);
        map.put("timestamp",timetamp);  //值應該爲毫秒數的字符串形式
        map.put("path", "/dubbo/findAll");
        map.put("version", "1.0.0");
        List<String> storedKeys = Arrays.stream(map.keySet()
                .toArray(new String[]{}))
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.toList());
        final String sign = storedKeys.stream()
                .map(key -> String.join("", key, map.get(key)))
                .collect(Collectors.joining()).trim()
                .concat("D19CF79F647A465AB9C5C66F430CAD28");//SECRETkey
        return DigestUtils.md5DigestAsHex(sign.getBytes()).toUpperCase();
    }


複製代碼

下面須要注意的 image.png學習

在網關中增長鑑權頭信息

image.png

請求的結果演示

經過的返回 image.png 5min超時的返回 image.png appKey填寫錯誤的返回 簽名image.png 錯誤的返回 image.png替換籤名插件的返回 image.pngui

sign插件的實現分析

Java中對

SignPlugin插件調用DefaultSignService中signVerify方法判斷簽名插件是否可用,若是可用獲取在全局插件存入的soulContext並調用verify方法lua

if (signData != null && signData.getEnabled()) {
  final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
  assert soulContext != null;
  return verify(soulContext, exchange);
}

複製代碼

驗證方法中判斷請求頭信息是否正確若是不正確就拋出log.error(「符號參數不完整,{}」,soulContext)異常url

if (StringUtils.isBlank(soulContext.getAppKey())
    || StringUtils.isBlank(soulContext.getSign())
    || StringUtils.isBlank(soulContext.getTimestamp())) {
  log.error("sign parameters are incomplete,{}", soulContext);
  return Pair.of(Boolean.FALSE, Constants.SIGN_PARAMS_ERROR);
}

複製代碼

判斷請求時間是否超時spa

if (between > delay) {
            return Pair.of(Boolean.FALSE, String.format(SoulResultEnum.SING_TIME_IS_TIMEOUT.getMsg(), delay));
        }

複製代碼

沒有超時繼續調用sign方法獲取認證數據,這個數據在soulAdmin中配置

AppAuthData appAuthData = SignAuthDataCache.getInstance().obtainAuthData(soulContext.getAppKey());

複製代碼

後面對appAuthData數據進行判斷,數據有錯誤就不經過對獲取的參數再次簽名,判斷假定的和再次簽名的是否同樣

String sigKey = SignUtils.generateSign(appAuthData.getAppSecret(), buildParamsMap(soulContext));

複製代碼

若是都驗證都經過就完成了認證訪問請求。

相關文章
相關標籤/搜索