feat: secret key auth
This commit is contained in:
@@ -210,8 +210,12 @@ public class ApiConfigService {
|
|||||||
|
|
||||||
NO_TIMESTAMP_OR_SIGN ("no timestamp or sign"),
|
NO_TIMESTAMP_OR_SIGN ("no timestamp or sign"),
|
||||||
|
|
||||||
|
NO_SECRETKEY ("no secretkey"),
|
||||||
|
|
||||||
SIGN_INVALID ("sign invalid"),
|
SIGN_INVALID ("sign invalid"),
|
||||||
|
|
||||||
|
SECRETKEY_INVALID ("secretkey invalid"),
|
||||||
|
|
||||||
NO_CUSTOM_AUTH ("no custom auth"),
|
NO_CUSTOM_AUTH ("no custom auth"),
|
||||||
|
|
||||||
CUSTOM_AUTH_REJECT ("custom auth reject"),
|
CUSTOM_AUTH_REJECT ("custom auth reject"),
|
||||||
@@ -229,6 +233,17 @@ public class ApiConfigService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ApiConfig getApiConfig(String app, String service, HttpMethod method, String path) {
|
||||||
|
ApiConfig ac = null;
|
||||||
|
for (String g : gatewayGroupService.currentGatewayGroupSet) {
|
||||||
|
ac = getApiConfig(service, method, path, g, app);
|
||||||
|
if (ac != null) {
|
||||||
|
return ac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ac;
|
||||||
|
}
|
||||||
|
|
||||||
public ApiConfig getApiConfig(String service, HttpMethod method, String path, String gatewayGroup, String app) {
|
public ApiConfig getApiConfig(String service, HttpMethod method, String path, String gatewayGroup, String app) {
|
||||||
ServiceConfig sc = serviceConfigMap.get(service);
|
ServiceConfig sc = serviceConfigMap.get(service);
|
||||||
if (sc != null) {
|
if (sc != null) {
|
||||||
@@ -256,91 +271,100 @@ public class ApiConfigService {
|
|||||||
WebUtils.getClientService(exchange), req.getMethod(), WebUtils.getClientReqPath(exchange));
|
WebUtils.getClientService(exchange), req.getMethod(), WebUtils.getClientReqPath(exchange));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<Object> canAccess(ServerWebExchange exchange, String app, String ip, String timestamp, String sign, String secretKey,
|
private Mono<Object> canAccess(ServerWebExchange exchange, String app, String ip, String timestamp, String sign, String secretKey,
|
||||||
String service, HttpMethod method, String path) {
|
String service, HttpMethod method, String path) {
|
||||||
|
|
||||||
ServiceConfig sc = serviceConfigMap.get(service);
|
ServiceConfig sc = serviceConfigMap.get(service);
|
||||||
if (sc == null) {
|
if (sc == null) {
|
||||||
if (!needAuth) {
|
if (!needAuth) {
|
||||||
return Mono.just(Access.YES);
|
return Mono.just(Access.YES);
|
||||||
} else {
|
} else {
|
||||||
return logWarnAndResult(service + Constants.Symbol.BLANK + Access.NO_SERVICE_CONFIG.getReason(), Access.NO_SERVICE_CONFIG);
|
return logAndResult(service + Constants.Symbol.BLANK + Access.NO_SERVICE_CONFIG.getReason(), Access.NO_SERVICE_CONFIG);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String api = ThreadContext.getStringBuilder().append(service).append(Constants.Symbol.BLANK).append(method.name()).append(Constants.Symbol.BLANK + path).toString();
|
String api = ThreadContext.getStringBuilder().append(service).append(Constants.Symbol.BLANK).append(method.name()).append(Constants.Symbol.BLANK + path).toString();
|
||||||
ApiConfig ac0 = null;
|
ApiConfig ac = getApiConfig(app, service, method, path);
|
||||||
for (String g : gatewayGroupService.currentGatewayGroupSet) {
|
|
||||||
ac0 = getApiConfig(service, method, path, g, app);
|
|
||||||
if (ac0 != null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ApiConfig ac = ac0;
|
|
||||||
if (ac == null) {
|
if (ac == null) {
|
||||||
if (!needAuth) {
|
if (!needAuth) {
|
||||||
return Mono.just(Access.YES);
|
return Mono.just(Access.YES);
|
||||||
} else {
|
} else {
|
||||||
return logWarnAndResult(api + " no api config", Access.NO_API_CONFIG);
|
return logAndResult(api + " no api config", Access.NO_API_CONFIG);
|
||||||
}
|
}
|
||||||
} else if (gatewayGroupService.currentGatewayGroupIn(ac.gatewayGroups)) {
|
} else if (gatewayGroupService.currentGatewayGroupIn(ac.gatewayGroups)) {
|
||||||
if (!ac.checkApp) {
|
if (!ac.checkApp) {
|
||||||
return allow(api, ac);
|
return allow(api, ac);
|
||||||
} else if (app != null && apiConifg2appsService.contains(ac.id, app) ) {
|
} else if (app != null && apiConifg2appsService.contains(ac.id, app)) {
|
||||||
if (ac.access == ApiConfig.ALLOW) {
|
if (ac.access == ApiConfig.ALLOW) {
|
||||||
App a = appService.getApp(app);
|
App a = appService.getApp(app);
|
||||||
if (a.useWhiteList && !a.allow(ip)) {
|
if (a.useWhiteList && !a.allow(ip)) {
|
||||||
return logWarnAndResult(ip + " not in " + app + " white list", Access.IP_NOT_IN_WHITE_LIST);
|
return logAndResult(ip + " not in " + app + " white list", Access.IP_NOT_IN_WHITE_LIST);
|
||||||
} else if (a.useAuth) {
|
} else if (a.useAuth) {
|
||||||
if (a.authType == App.SIGN_AUTH) {
|
if (a.authType == App.AUTH_TYPE.SIGN) {
|
||||||
if (StringUtils.isBlank(timestamp) || StringUtils.isBlank(sign)) {
|
return authSign(ac, a, timestamp, sign);
|
||||||
return logWarnAndResult(app + " lack timestamp " + timestamp + " or sign " + sign, Access.NO_TIMESTAMP_OR_SIGN);
|
} else if (a.authType == App.AUTH_TYPE.SECRETKEY) {
|
||||||
} else if (!validate(app, timestamp, a.secretkey, sign)) {
|
return authSecretkey(ac , a, secretKey);
|
||||||
return logWarnAndResult(app + " sign " + sign + " invalid", Access.SIGN_INVALID);
|
} else if (customAuth == null) {
|
||||||
} else {
|
return logAndResult(app + " no custom auth", Access.NO_CUSTOM_AUTH);
|
||||||
return Mono.just(ac);
|
|
||||||
}
|
|
||||||
} else if (customAuth == null) {
|
|
||||||
return logWarnAndResult(app + " no custom auth", Access.NO_CUSTOM_AUTH);
|
|
||||||
} else {
|
|
||||||
return customAuth.auth(exchange, app, ip, timestamp, sign, secretKey, a).flatMap(v -> {
|
|
||||||
if (v == Access.YES) {
|
|
||||||
return Mono.just(ac);
|
|
||||||
} else {
|
|
||||||
return Mono.just(Access.CUSTOM_AUTH_REJECT);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Mono.just(ac);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return logWarnAndResult("cant access " + api, Access.CANT_ACCESS_SERVICE_API);
|
return customAuth.auth(exchange, app, ip, timestamp, sign, secretKey, a).flatMap(v -> {
|
||||||
|
if (v == Access.YES) {
|
||||||
|
return Mono.just(ac);
|
||||||
|
} else {
|
||||||
|
return Mono.just(Access.CUSTOM_AUTH_REJECT);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return Mono.just(ac);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return logWarnAndResult(app + " not in " + api + " legal apps", Access.APP_NOT_IN_API_LEGAL_APPS);
|
return logAndResult("cant access " + api, Access.CANT_ACCESS_SERVICE_API);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return logAndResult(app + " not in " + api + " legal apps", Access.APP_NOT_IN_API_LEGAL_APPS);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return logWarnAndResult(gatewayGroupService.currentGatewayGroupSet + " cant proxy " + api, Access.GATEWAY_GROUP_CANT_PROXY_API);
|
return logAndResult(gatewayGroupService.currentGatewayGroupSet + " cant proxy " + api, Access.GATEWAY_GROUP_CANT_PROXY_API);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Mono<Object> allow(String api, ApiConfig ac) {
|
private static Mono authSign(ApiConfig ac, App a, String timestamp, String sign) {
|
||||||
if (ac.access == ApiConfig.ALLOW) {
|
if (StringUtils.isAnyBlank(timestamp, sign)) {
|
||||||
|
return logAndResult(a.app + " lack timestamp " + timestamp + " or sign " + sign, Access.NO_TIMESTAMP_OR_SIGN);
|
||||||
|
} else if (validate(a.app, timestamp, a.secretkey, sign)) {
|
||||||
return Mono.just(ac);
|
return Mono.just(ac);
|
||||||
} else {
|
} else {
|
||||||
return logWarnAndResult("cant access " + api, Access.CANT_ACCESS_SERVICE_API);
|
return logAndResult(a.app + " sign " + sign + " invalid", Access.SIGN_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Mono logWarnAndResult(String msg, Access access) {
|
|
||||||
log.warn(msg);
|
|
||||||
return Mono.just(access);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean validate(String app, String timestamp, String secretKey, String sign) {
|
private static boolean validate(String app, String timestamp, String secretKey, String sign) {
|
||||||
StringBuilder b = ThreadContext.getStringBuilder();
|
StringBuilder b = ThreadContext.getStringBuilder();
|
||||||
b.append(app).append(Constants.Symbol.UNDERLINE).append(timestamp).append(Constants.Symbol.UNDERLINE).append(secretKey);
|
b.append(app).append(Constants.Symbol.UNDERLINE).append(timestamp).append(Constants.Symbol.UNDERLINE).append(secretKey);
|
||||||
return sign.equalsIgnoreCase(DigestUtils.md532(b.toString()));
|
return sign.equalsIgnoreCase(DigestUtils.md532(b.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Mono authSecretkey(ApiConfig ac, App a, String secretKey) {
|
||||||
|
if (StringUtils.isBlank(secretKey)) {
|
||||||
|
return logAndResult(a.app + " lack secretKey " + secretKey, Access.NO_SECRETKEY);
|
||||||
|
} else if (a.secretkey.equals(secretKey)) {
|
||||||
|
return Mono.just(ac);
|
||||||
|
} else {
|
||||||
|
return logAndResult(a.app + " secretkey " + secretKey + " invalid", Access.SECRETKEY_INVALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Mono<Object> allow(String api, ApiConfig ac) {
|
||||||
|
if (ac.access == ApiConfig.ALLOW) {
|
||||||
|
return Mono.just(ac);
|
||||||
|
} else {
|
||||||
|
return logAndResult("cant access " + api, Access.CANT_ACCESS_SERVICE_API);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Mono logAndResult(String msg, Access access) {
|
||||||
|
log.warn(msg);
|
||||||
|
return Mono.just(access);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,9 +35,11 @@ public class App {
|
|||||||
|
|
||||||
public static final int DELETED = 1;
|
public static final int DELETED = 1;
|
||||||
|
|
||||||
public static final int SIGN_AUTH = 1;
|
static interface AUTH_TYPE {
|
||||||
|
static final int SIGN = 1;
|
||||||
public static final int CUSTOM_AUTH = 2;
|
static final int CUSTOM = 2;
|
||||||
|
static final int SECRETKEY = 3;
|
||||||
|
}
|
||||||
|
|
||||||
public int isDeleted = 0; // tb_app_auth.is_deleted
|
public int isDeleted = 0; // tb_app_auth.is_deleted
|
||||||
|
|
||||||
@@ -60,7 +62,7 @@ public class App {
|
|||||||
private Map<String, String[]> ips = new HashMap<>(6);
|
private Map<String, String[]> ips = new HashMap<>(6);
|
||||||
|
|
||||||
public void setUseAuth(int i) {
|
public void setUseAuth(int i) {
|
||||||
if (i == 1) {
|
if (i == AUTH_TYPE.SIGN || i == AUTH_TYPE.SECRETKEY || i == AUTH_TYPE.CUSTOM) {
|
||||||
useAuth = true;
|
useAuth = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user