| | |
| | | package com.ruoyi.gateway.filter; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.core.constant.HttpStatus; |
| | |
| | | import org.springframework.cloud.gateway.filter.GlobalFilter; |
| | | import org.springframework.core.Ordered; |
| | | import org.springframework.core.io.buffer.DataBuffer; |
| | | import org.springframework.core.io.buffer.DataBufferUtils; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.HttpMethod; |
| | | import org.springframework.http.server.reactive.ServerHttpRequest; |
| | |
| | | import reactor.core.publisher.Flux; |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.Comparator; |
| | |
| | | } |
| | | String sing = request.getHeaders().getFirst(TokenConstants.SING); |
| | | String nonce_str = request.getHeaders().getFirst(TokenConstants.NONCE_STR); |
| | | if (parameter_signature && StringUtils.isEmpty(sing)) { |
| | | return unauthorizedResponse(exchange, "签名不能为空!"); |
| | | } |
| | | if (parameter_signature && StringUtils.isEmpty(nonce_str)) { |
| | | return unauthorizedResponse(exchange, "签名不能为空!"); |
| | | } |
| | | if(parameter_signature && !authSign(exchange)){ |
| | | return unauthorizedResponse(exchange, "签名不通过!"); |
| | | // if (parameter_signature && StringUtils.isEmpty(sing)) { |
| | | // return unauthorizedResponse(exchange, "签名不能为空!"); |
| | | // } |
| | | // if (parameter_signature && StringUtils.isEmpty(nonce_str)) { |
| | | // return unauthorizedResponse(exchange, "签名不能为空!"); |
| | | // } |
| | | if(parameter_signature){ |
| | | return authSign(exchange, chain, sing, nonce_str); |
| | | } |
| | | return chain.filter(exchange.mutate().request(mutate.build()).build()); |
| | | } |
| | |
| | | |
| | | /** |
| | | * 校验签名 |
| | | * @param exchange |
| | | * @return |
| | | */ |
| | | private boolean authSign(ServerWebExchange exchange){ |
| | | return false; |
| | | private Mono<Void> authSign(ServerWebExchange exchange, GatewayFilterChain chain, String sing, String nonce_str){ |
| | | return DataBufferUtils.join(exchange.getRequest().getBody()) |
| | | .flatMap(dataBuffer -> { |
| | | byte[] bytes = new byte[dataBuffer.readableByteCount()]; |
| | | dataBuffer.read(bytes); |
| | | String bodyString = new String(bytes, StandardCharsets.UTF_8); |
| | | log.info("请求参数:{}", bodyString); |
| | | if(!authSign(JSON.parseObject(bodyString), sing, nonce_str)){ |
| | | return unauthorizedResponse(exchange, "签名验证失败!"); |
| | | } |
| | | DataBufferUtils.release(dataBuffer); |
| | | Flux<DataBuffer> cachedFlux = Flux.defer(() -> { |
| | | DataBuffer buffer = exchange.getResponse().bufferFactory() |
| | | .wrap(bytes); |
| | | return Mono.just(buffer); |
| | | }); |
| | | ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) { |
| | | @Override |
| | | public Flux<DataBuffer> getBody() { |
| | | return cachedFlux; |
| | | } |
| | | }; |
| | | return chain.filter(exchange.mutate().request(mutatedRequest) |
| | | .build()); |
| | | }); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 签名校验 |
| | | * @param httpRequestDecorator |
| | | * @return |
| | | */ |
| | | private boolean authSign(ServerHttpRequestDecorator httpRequestDecorator) { |
| | | HttpHeaders headers = httpRequestDecorator.getHeaders(); |
| | | Flux<DataBuffer> body = httpRequestDecorator.getBody(); |
| | | AtomicReference<JSONObject> jsonObject = new AtomicReference<>(new JSONObject()); |
| | | httpRequestDecorator.getBody().map(dataBuffers -> dataBuffers.toString()); |
| | | JSONObject params = jsonObject.get(); |
| | | String sign = headers.getFirst(TokenConstants.SING); |
| | | if(StringUtils.isEmpty(sign)){ |
| | | return false; |
| | | } |
| | | String nonce_str = headers.getFirst(TokenConstants.NONCE_STR); |
| | | if(StringUtils.isEmpty(nonce_str)){ |
| | | return false; |
| | | } |
| | | |
| | | String signUrlEncode = localSignUrl(params, nonce_str); |
| | | private boolean authSign(JSONObject jsonStr, String sign, String nonce_str) { |
| | | String signUrlEncode = localSignUrl(jsonStr, nonce_str); |
| | | signUrlEncode = signUrlEncode.replaceAll("& #40;", "\\(") |
| | | .replaceAll("& #41;", "\\)") |
| | | .replaceAll("\\+", " "); |
| | |
| | | try { |
| | | signByte = HMACSHA1.HmacSHA1Encrypt(signUrl, encryptKey); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new RuntimeException(e); |
| | | } |
| | | String localSign = Base64.encodeBase64String(signByte); |