The Soul Gateway learns from the Sign plugin

Author: tang Tian

introduce

Sign plug-in A plug-in used to authenticate requests with signatures

AK/SK introduction

AK/SK (Access key ID/Secret access key) An access key consists of an access key ID (AK) and a secret access key (SK). It is used for authentication and authentication of user invocation behaviors.

Plugin use – use (/ dubbo/findAll) as an example

Add it in the pom.xml file of SoulBootstrapsignThe support of

<! -- 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-->Copy the code

Added appKey and secretKey

Configure the selector and the rule

Add selectorAdd rule

Added the obtaining authentication service

Add an external access method to your own service

@GetMapping("/authUrl") public String authUrl() { Map<String, String> map = Maps.newHashMapWithExpectedSize(2); // TIMESTAMP is a String of milliseconds. 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); // The value should be a string of milliseconds map.put("path", "/dubbo/findAll"); The map. The 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(); }Copy the code

So here’s something to notice

Add the authentication header information to the gateway

Request result demo

Return throughReturn a 5 minute timeoutAppKey filled in error return signatureError returnReplace the return of the signature plug-in

Implementation analysis of sign plug-in

In Java for

The SignPlugin plugin calls the signVerify method in DefaultSignService to determine whether the signed plug-in is available. If so, obtain the soulContext stored in the global plug-in and call Verify

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

Error (” Symbol parameter incomplete, {} “, soulContext) is raised if the request header information is incorrect

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);
}

Copy the code

Determines whether the request time has timed out

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

Copy the code

Continue calling the sign method without timeout to get authentication data, which is configured in soulAdmin

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

Copy the code

After that, appAuthData data is judged. If there are errors in the data, the obtained parameters are not re-signed to determine whether the assumed and re-signed parameters are the same

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

Copy the code

If both authentications pass, the authentication access request is completed.