This is the 21st day of my participation in the August Text Challenge.More challenges in August
Blacklist Configuration
As the name suggests, is not accessible address. To implement a custom filter BlackListUrlFilter, you need to configure the blacklist address list blacklistUrl. Of course, other requirements can also implement custom filter rules.
spring:
cloud:
gateway:
routes:
# System module
- id: demo-system
uri: lb://demo-system
predicates:
- Path=/system/**
filters:
- StripPrefix=1
- name: BlackListUrlFilter
args:
blacklistUrl:
- /user/list
Copy the code
Whitelist Configuration
As the name suggests, this is the address that is allowed to access. And you don’t need to log in to access it. Set whites in ignore to allow anonymous access.
# whitelist is not checked
ignore:
whites:
- /auth/logout
- /auth/login
- /*/v2/api-docs
- /csrf
Copy the code
Global filter
The global filter applies to all routes and does not need to be configured separately. We can use it to implement many unified business requirements, such as permission authentication, IP access restriction, and so on. The current unified gateway authentication AuthFilter. Java is the global filter used.
The separate definition only needs to implement the GlobalFilter, Ordered interfaces.
package com.demo.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/** * global filter ** /
@Component
public class AuthFilter implements GlobalFilter.Ordered
{
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
{
String token = exchange.getRequest().getQueryParams().getFirst("token");
if (null == token)
{
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add("Content-Type"."application/json; charset=utf-8");
String message = "{"message":"The request token information cannot be empty"}";
DataBuffer buffer = response.bufferFactory().wrap(message.getBytes());
return response.writeWith(Mono.just(buffer));
}
return chain.filter(exchange);
}
@Override
public int getOrder(a)
{
return 0; }}Copy the code
Sentinel current limiting is implemented
Sentinel supports stream limiting for mainstream API gateways such as Spring Cloud Gateway and Netflix Zuul.
1. Add dependencies
<! -- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<! -- SpringCloud Alibaba Sentinel Gateway -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
Copy the code
2. Traffic limiting rule configuration class
package com.demo.gateway.config;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import com.demo.gateway.handler.SentinelFallbackHandler;
/** * Gateway traffic limiting configuration ** /
@Configuration
public class GatewayConfig
{
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelFallbackHandler sentinelGatewayExceptionHandler(a)
{
return new SentinelFallbackHandler();
}
@Bean
@Order(-1)
public GlobalFilter sentinelGatewayFilter(a)
{
return new SentinelGatewayFilter();
}
@PostConstruct
public void doInit(a)
{
// Load the gateway traffic limiting rule
initGatewayRules();
}
/** * Gateway traffic limiting rule */
private void initGatewayRules(a)
{
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("demo-system")
.setCount(3) // Traffic limiting threshold
.setIntervalSec(60)); // Statistics time window, in seconds, default is 1 second
// Load the gateway traffic limiting ruleGatewayRuleManager.loadRules(rules); }}Copy the code
3. Test and verify that traffic limiting is successful if an exception occurs when accessing system services for three times within one minute.
Sentinel packet current limiting
Configure traffic limiting for demo-system and Demo-Gen packets
1. Application. Yml configuration file
spring:
cloud:
gateway:
routes:
# System module
- id: demo-system
uri: lb://demo-system
predicates:
- Path=/system/**
filters:
- StripPrefix=1
# Code generation
- id: demo-gen
uri: lb://demo-gen
predicates:
- Path=/code/**
filters:
- StripPrefix=1
Copy the code
2. Traffic limiting rule configuration class
package com.demo.gateway;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import com.demo.gateway.handler.SentinelFallbackHandler;
/** * Gateway traffic limiting configuration ** /
@Configuration
public class GatewayConfig
{
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelFallbackHandler sentinelGatewayExceptionHandler(a)
{
return new SentinelFallbackHandler();
}
@Bean
@Order(-1)
public GlobalFilter sentinelGatewayFilter(a)
{
return new SentinelGatewayFilter();
}
@PostConstruct
public void doInit(a)
{
// Load the gateway traffic limiting rule
initGatewayRules();
}
/** * Gateway traffic limiting rule */
private void initGatewayRules(a)
{
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("system-api")
.setCount(3) // Traffic limiting threshold
.setIntervalSec(60)); // Statistics time window, in seconds, default is 1 second
rules.add(new GatewayFlowRule("code-api")
.setCount(5) // Traffic limiting threshold
.setIntervalSec(60));
// Load the gateway traffic limiting rule
GatewayRuleManager.loadRules(rules);
// Load the traffic limiting group
initCustomizedApis();
}
/** * Traffic limiting group */
private void initCustomizedApis(a)
{
Set<ApiDefinition> definitions = new HashSet<>();
/ / the demo - system group
ApiDefinition api1 = new ApiDefinition("system-api").setPredicateItems(new HashSet<ApiPredicateItem>()
{
private static final long serialVersionUID = 1L;
{
// Matches all requests from /user and its subpath
add(new ApiPathPredicateItem().setPattern("/system/user/**") .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX)); }});/ / the demo - gen group
ApiDefinition api2 = new ApiDefinition("code-api").setPredicateItems(new HashSet<ApiPredicateItem>()
{
private static final long serialVersionUID = 1L;
{
// Matches only /job/list
add(new ApiPathPredicateItem().setPattern("/code/gen/list")); }}); definitions.add(api1); definitions.add(api2);// Load the traffic limiting groupGatewayApiDefinitionManager.loadApiDefinitions(definitions); }}Copy the code
Visit: http://localhost:8080/system/user/list (trigger current limiting access: http://localhost:8080/system/role/list (not trigger current limiting access: http://localhost:8080/code/gen/list (trigger current limiting access: http://localhost:8080/code/gen/xxxx (not trigger current limit)
[#]Sentinel Custom exception
Sentinel supports custom exception handling in order to show more user-friendly traffic limiting cues.
Solution 1: YML configuration
# Spring Spring: cloud: sentinel: SCG: fallback: mode: response Response-body: '{"code":403," MSG ":" Request exceeded the maximum number, please try again later "}'Copy the code
Scheme 2: GatewayConfig injection Bean
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelFallbackHandler sentinelGatewayExceptionHandler()
{
return new SentinelFallbackHandler();
}
Copy the code
SentinelFallbackHandler.java
package com.demo.gateway.handler;
import java.nio.charset.StandardCharsets;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
import reactor.core.publisher.Mono;
/** * Custom traffic limiting exception handling ** /
public class SentinelFallbackHandler implements WebExceptionHandler
{
private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange)
{
ServerHttpResponse serverHttpResponse = exchange.getResponse();
serverHttpResponse.getHeaders().add("Content-Type"."application/json; charset=UTF-8");
byte[] datas = "{"code": 429,"msg":"The request exceeded the maximum number, please try again later"}".getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(datas);
return serverHttpResponse.writeWith(Mono.just(buffer));
}
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex)
{
if (exchange.getResponse().isCommitted())
{
return Mono.error(ex);
}
if(! BlockException.isBlockException(ex)) {return Mono.error(ex);
}
return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange));
}
private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable)
{
returnGatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable); }}Copy the code