Commit a3a53293 by 刘鑫

CI: 添加外部接口AK校验, 并且不在校验白名单内的接口不再放行

1 parent 7c3debd7
package com.dituhui.pea.gateway.config; package com.dituhui.pea.gateway.config;
import java.util.Set; import com.alibaba.fastjson.JSON;
import com.dituhui.pea.common.Result;
import com.dituhui.pea.constants.Globals;
import com.dituhui.pea.enums.RedisKeyGroup;
import com.dituhui.pea.gateway.commom.RedisService;
import com.dituhui.pea.pojo.UserLoginDTO;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import com.dituhui.pea.constants.Globals;
import com.dituhui.pea.enums.RedisKeyGroup;
import com.dituhui.pea.gateway.commom.RedisService;
import com.dituhui.pea.pojo.UserLoginDTO;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;
@Component @Component
@Slf4j @Slf4j
public class AuthFilter implements GlobalFilter, Ordered { public class AuthFilter implements GlobalFilter, Ordered {
...@@ -73,7 +80,7 @@ public class AuthFilter implements GlobalFilter, Ordered { ...@@ -73,7 +80,7 @@ public class AuthFilter implements GlobalFilter, Ordered {
// ak登录处理 // ak登录处理
if (StringUtils.isEmpty(authToken)) { if (StringUtils.isEmpty(authToken)) {
String ak = exchange.getRequest().getQueryParams().getFirst("ak"); final String ak = getParams(exchange, "ak", headers);
if (log.isTraceEnabled()) { if (log.isTraceEnabled()) {
log.trace("ak is {}", ak); log.trace("ak is {}", ak);
} }
...@@ -85,6 +92,10 @@ public class AuthFilter implements GlobalFilter, Ordered { ...@@ -85,6 +92,10 @@ public class AuthFilter implements GlobalFilter, Ordered {
// 验证成功,设置为管理员 // 验证成功,设置为管理员
// AppDTO appDTO = gson.fromJson(value, AppDTO.class); // AppDTO appDTO = gson.fromJson(value, AppDTO.class);
// String secret = appDTO.getSecret(); // String secret = appDTO.getSecret();
//TODO 参数签名校验
final String sign = getParams(exchange, "sign", headers);
//计算签名
userDTO = new UserLoginDTO(); userDTO = new UserLoginDTO();
userDTO.setId(Globals.SUPER_ADMIN_ID); userDTO.setId(Globals.SUPER_ADMIN_ID);
} }
...@@ -93,6 +104,7 @@ public class AuthFilter implements GlobalFilter, Ordered { ...@@ -93,6 +104,7 @@ public class AuthFilter implements GlobalFilter, Ordered {
if (userDTO == null) { if (userDTO == null) {
log.info("未授权访问{} ip:{}", url, getRemoteIP(exchange)); log.info("未授权访问{} ip:{}", url, getRemoteIP(exchange));
return noPower(exchange);
} else { } else {
log.info("用户:{} id:{} 访问{}", userDTO.getAccount(), userDTO.getId(), url); log.info("用户:{} id:{} 访问{}", userDTO.getAccount(), userDTO.getId(), url);
// 获取当前的请求对象信息 // 获取当前的请求对象信息
...@@ -104,10 +116,51 @@ public class AuthFilter implements GlobalFilter, Ordered { ...@@ -104,10 +116,51 @@ public class AuthFilter implements GlobalFilter, Ordered {
// SecurityContextHolder.getContext().setAuthentication(authentication); // SecurityContextHolder.getContext().setAuthentication(authentication);
return chain.filter(exchange.mutate().request(builder.build()).build()); return chain.filter(exchange.mutate().request(builder.build()).build());
} }
}
return chain.filter(exchange); /**
* 解析所有参数
*
*/
private Map<String, String> parseGetParams(ServerWebExchange exchange) {
// params
Map<String, String> params = Maps.newHashMap();
//请求路劲参数
Map<String, String> urlRequestParams = exchange.getRequest().getQueryParams().toSingleValueMap();
return params;
} }
private String getParams(ServerWebExchange exchange, String paramKey, HttpHeaders headers) {
String param = exchange.getRequest().getQueryParams().getFirst(paramKey);
if (StringUtils.isBlank(param)) {
param = headers.getFirst(paramKey);
}
return param;
}
/**
* 网关拒绝,返回Result
*/
private Mono<Void> noPower(ServerWebExchange serverWebExchange) {
// 权限不够拦截
serverWebExchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
Result<?> data = Result.failed();
DataBuffer buffer = serverWebExchange.getResponse().bufferFactory().wrap(JSON.toJSONString(data).getBytes(StandardCharsets.UTF_8));
ServerHttpResponse response = serverWebExchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
//指定编码,否则在浏览器中会中文乱码
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
return response.writeWith(Mono.just(buffer));
}
/** /**
* 客户端ip * 客户端ip
* *
......
/*
* Begin license text.
* Copyright (c) 2020 — 2021 Liu Xin && Zhang Lei lsy_xin@163.com
* All rights reserved
* End license text.
*/
package com.dituhui.pea.gateway.utils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
/**
* @author zl
*/
public class SignUtil {
/**
* 对输入参数签名
*
* @param params 参数
* @param secret 密钥
* @return
* @throws IOException
*/
public static String signRequest(Map<String, String> params, String secret) {
try {
// 第一步:参数排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
for (String key : keys) {
String value = params.get(key);
if (StringUtils.isNotEmpty(key) && !StringUtils.equalsIgnoreCase(key, "sign")
&& StringUtils.isNotEmpty(value)) {
query.append(key).append(value);
}
}
// 第三步:使用MD5/HMAC加密
return DigestUtils.md5Hex(query.toString() + secret);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!