下面列出了org.springframework.http.server.reactive.ServerHttpRequest#getMethodValue ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 1.首先网关检查token是否有效,无效直接返回401,不调用签权服务
* 2.调用签权服务器看是否对该请求有权限,有权限进入下一个filter,没有权限返回401
*
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String authentication = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
String method = request.getMethodValue();
String url = request.getPath().value();
log.debug("url:{},method:{},headers:{}", url, method, request.getHeaders());
//不需要网关签权的url
if (authService.ignoreAuthentication(url)) {
return chain.filter(exchange);
}
//调用签权服务看用户是否有权限,若有权限进入下一个filter
if (authService.hasPermission(authentication, url, method)) {
ServerHttpRequest.Builder builder = request.mutate();
//TODO 转发的请求都加上服务间认证token
builder.header(X_CLIENT_TOKEN, "TODO zhoutaoo添加服务间简单认证");
//将jwt token中的用户信息传给服务
builder.header(X_CLIENT_TOKEN_USER, authService.getJwt(authentication).getClaims());
return chain.filter(exchange.mutate().request(builder.build()).build());
}
return unauthorized(exchange);
}
/**
* 1.首先网关检查token是否有效,无效直接返回401,不调用签权服务
* 2.调用签权服务器看是否对该请求有权限,有权限进入下一个filter,没有权限返回401
*
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String authentication = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
String method = request.getMethodValue();
String url = request.getPath().value();
log.debug("url:{},method:{},headers:{}", url, method, request.getHeaders());
//不需要网关签权的url
if (authService.ignoreAuthentication(url)) {
return chain.filter(exchange);
}
//调用签权服务看用户是否有权限,若有权限进入下一个filter
if (permissionService.permission(authentication, url, method)) {
ServerHttpRequest.Builder builder = request.mutate();
//TODO 转发的请求都加上服务间认证token
builder.header(X_CLIENT_TOKEN, "TODO zhoutaoo添加服务间简单认证");
//将jwt token中的用户信息传给服务
builder.header(X_CLIENT_TOKEN_USER, getUserToken(authentication));
return chain.filter(exchange.mutate().request(builder.build()).build());
}
return unauthorized(exchange);
}
/**
* 获取token字段,如果能获取到就 pass,获取不到就直接返回401错误,
* chain.filter(exchange)之前的就是 “pre” 部分,之后的也就是then里边的是 “post” 部分
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String authentication = request.getHeaders().getFirst("AUTH");
String method = request.getMethodValue();
String url = request.getPath().value();
LogBack.info("url:{},method:{},headers:{}", url, method, request.getHeaders());
//不需要网关签权的url
if (authService.ignoreAuthentication(url) || StringUtils.startsWith(url, "/api")) {
return chain.filter(exchange);
}
// 如果请求未携带token信息, 直接跳出
if (StringUtils.isBlank(authentication) || !authentication.contains(BEARER)) {
LogBack.error("url:{},method:{},headers:{}, 请求未携带token信息", url, method, request.getHeaders());
return unAuthorized(exchange, StatusEnum.PARAM_ILLEGAL);
}
long expire = authService.getExpire(authentication);
// 过期
if(expire<0){
return unAuthorized(exchange,StatusEnum.LOGIN_EXPIRED);
}
AuthToken authToken = authService.getAuthToken(authentication);
String jwtToken = authToken.getAccess_token();
//调用签权服务看用户是否有权限,若有权限进入下一个filter
if (authService.commonAuthentication(url) || authService.hasPermission(jwtToken, url, method) ) {
ServerHttpRequest.Builder builder = request.mutate();
builder.header(X_CLIENT_TOKEN, "TODO 添加服务间简单认证");//TODO 转发的请求都加上服务间认证token
//将jwt token中的用户信息传给服务
builder.header(X_CLIENT_TOKEN_USER, authService.getJwt(jwtToken).getClaims());
builder.header(HttpHeaders.AUTHORIZATION,BEARER+jwtToken);
return chain.filter(exchange.mutate().request(builder.build()).build());
}
return unAuthorized(exchange,StatusEnum.UN_AUTHORIZED);
}
@Override
public Mono<Void> filterBlackList(ServerWebExchange exchange) {
Stopwatch stopwatch = Stopwatch.createStarted();
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
try {
URI originUri = getGatewayOriginalRequestUrl(exchange);
if (originUri != null) {
String requestIp = FebsUtil.getServerHttpRequestIpAddress(request);
String requestMethod = request.getMethodValue();
AtomicBoolean forbid = new AtomicBoolean(false);
Set<Object> blackList = routeEnhanceCacheService.getBlackList(requestIp);
blackList.addAll(routeEnhanceCacheService.getBlackList());
doBlackListCheck(forbid, blackList, originUri, requestMethod);
log.info("Blacklist verification completed - {}", stopwatch.stop());
if (forbid.get()) {
return FebsUtil.makeWebFluxResponse(response, MediaType.APPLICATION_JSON_VALUE,
HttpStatus.NOT_ACCEPTABLE, new FebsResponse().message("黑名单限制,禁止访问"));
}
} else {
log.info("Request IP not obtained, no blacklist check - {}", stopwatch.stop());
}
} catch (Exception e) {
log.warn("Blacklist verification failed : {} - {}", e.getMessage(), stopwatch.stop());
}
return null;
}
@Override
public Mono<Void> filterRateLimit(ServerWebExchange exchange) {
Stopwatch stopwatch = Stopwatch.createStarted();
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
try {
URI originUri = getGatewayOriginalRequestUrl(exchange);
if (originUri != null) {
String requestIp = FebsUtil.getServerHttpRequestIpAddress(request);
String requestMethod = request.getMethodValue();
AtomicBoolean limit = new AtomicBoolean(false);
Object o = routeEnhanceCacheService.getRateLimitRule(originUri.getPath(), METHOD_ALL);
if (o == null) {
o = routeEnhanceCacheService.getRateLimitRule(originUri.getPath(), requestMethod);
}
if (o != null) {
RateLimitRule rule = JSONObject.parseObject(o.toString(), RateLimitRule.class);
Mono<Void> result = doRateLimitCheck(limit, rule, originUri, requestIp, requestMethod, response);
log.info("Rate limit verification completed - {}", stopwatch.stop());
if (result != null) {
return result;
}
}
} else {
log.info("Request IP not obtained, no rate limit filter - {}", stopwatch.stop());
}
} catch (Exception e) {
log.warn("Current limit failure : {} - {}", e.getMessage(), stopwatch.stop());
}
return null;
}
/**
* 是否拦截
*
* @param request request
* @return boolean
* @author tangyi
* @date 2019/06/19 20:06
*/
private boolean shouldFilter(ServerHttpRequest request) {
// enabled不为true
Map<String, String> previewConfigMap = LoadingCacheHelper.getInstance().get(PreviewConfigLoader.class, PreviewConfigLoader.PREVIEW_ENABLE);
if (previewConfigMap == null || previewConfigMap.isEmpty() || !previewConfigMap.containsKey(PreviewConfigLoader.PREVIEW_ENABLE)) {
return true;
}
// 演示环境下,只拦截对默认租户的修改操作
if ("true".equals(previewConfigMap.get(PreviewConfigLoader.PREVIEW_ENABLE)) && GatewayConstant.DEFAULT_TENANT_CODE
.equals(request.getHeaders().getFirst(GatewayConstant.TENANT_CODE_HEADER))) {
String method = request.getMethodValue(), uri = request.getURI().getPath();
// GET请求、POST请求
if (StrUtil.equalsIgnoreCase(method, HttpMethod.GET.name()))
return false;
if (StrUtil.equalsIgnoreCase(method, HttpMethod.POST.name()) && !StrUtil.containsIgnoreCase(uri, "delete")
&& !StrUtil.containsIgnoreCase(uri, "menu"))
return false;
// 拦截DELETE请求
if (StrUtil.equalsIgnoreCase(method, HttpMethod.DELETE.name()) && !StrUtil
.containsIgnoreCase(uri, "attachment"))
return true;
// 不能修改路由
if (StrUtil.containsIgnoreCase(uri, "/route/") && (
StrUtil.equalsIgnoreCase(method, HttpMethod.DELETE.name()) || StrUtil
.equalsIgnoreCase(method, HttpMethod.PUT.name()) || StrUtil
.equalsIgnoreCase(method, HttpMethod.POST.name())))
return true;
// URL白名单
return !isIgnore(uri);
}
return false;
}
/**
* 获取token字段,如果能获取到就 pass,获取不到就直接返回401错误,
* chain.filter(exchange)之前的就是 “pre” 部分,之后的也就是then里边的是 “post” 部分
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String authentication = request.getHeaders().getFirst("AUTH");
String method = request.getMethodValue();
String url = request.getPath().value();
LogBack.info("url:{},method:{},headers:{}", url, method, request.getHeaders());
//不需要网关签权的url
if (authService.ignoreAuthentication(url) || StringUtils.startsWith(url, "/api")) {
return chain.filter(exchange);
}
// 如果请求未携带token信息, 直接跳出
if (StringUtils.isBlank(authentication) || !authentication.contains(BEARER)) {
LogBack.error("url:{},method:{},headers:{}, 请求未携带token信息", url, method, request.getHeaders());
return unAuthorized(exchange, StatusEnum.PARAM_ILLEGAL);
}
long expire = authService.getExpire(authentication);
// 过期
if(expire<0){
return unAuthorized(exchange,StatusEnum.LOGIN_EXPIRED);
}
AuthToken authToken = authService.getAuthToken(authentication);
String jwtToken = authToken.getAccess_token();
//调用签权服务看用户是否有权限,若有权限进入下一个filter
if (authService.commonAuthentication(url) || authService.hasPermission(jwtToken, url, method) ) {
ServerHttpRequest.Builder builder = request.mutate();
builder.header(X_CLIENT_TOKEN, "TODO 添加服务间简单认证");//TODO 转发的请求都加上服务间认证token
//将jwt token中的用户信息传给服务
builder.header(X_CLIENT_TOKEN_USER, authService.getJwt(jwtToken).getClaims());
builder.header(HttpHeaders.AUTHORIZATION,BEARER+jwtToken);
return chain.filter(exchange.mutate().request(builder.build()).build());
}
return unAuthorized(exchange,StatusEnum.UN_AUTHORIZED);
}
public void sendLog(ServerWebExchange exchange, Exception ex) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
try {
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
int httpStatus = response.getStatusCode().value();
String requestPath = request.getURI().getPath();
String method = request.getMethodValue();
Map<String, String> headers = request.getHeaders().toSingleValueMap();
Map data = Maps.newHashMap();
GatewayContext gatewayContext = exchange.getAttribute(GatewayContext.CACHE_GATEWAY_CONTEXT);
if(gatewayContext!=null){
data = gatewayContext.getAllRequestData().toSingleValueMap();
}
String serviceId = null;
if (route != null) {
serviceId = route.getUri().toString().replace("lb://", "");
}
String ip = ReactiveWebUtils.getRemoteAddress(exchange);
String userAgent = headers.get(HttpHeaders.USER_AGENT);
Object requestTime = exchange.getAttribute("requestTime");
String error = null;
if (ex != null) {
error = ex.getMessage();
}
if (ignore(requestPath)) {
return;
}
Map<String, Object> map = Maps.newHashMap();
map.put("requestTime", requestTime);
map.put("serviceId", serviceId == null ? defaultServiceId : serviceId);
map.put("httpStatus", httpStatus);
map.put("headers", JSONObject.toJSON(headers));
map.put("path", requestPath);
map.put("params", JSONObject.toJSON(data));
map.put("ip", ip);
map.put("method", method);
map.put("userAgent", userAgent);
map.put("responseTime", new Date());
map.put("error", error);
Mono<Authentication> authenticationMono = exchange.getPrincipal();
Mono<OpenUserDetails> authentication = authenticationMono
.map(Authentication::getPrincipal)
.cast(OpenUserDetails.class);
authentication.subscribe(user ->
map.put("authentication", JSONObject.toJSONString(user))
);
amqpTemplate.convertAndSend(QueueConstants.QUEUE_ACCESS_LOGS, map);
} catch (Exception e) {
log.error("access logs save error:{}", e);
}
}