我正试图在微观服务结构中为春季云云反应的AccountFilter进行单位测试。 关口正在使用网络F奢侈品,而如果最终点是公开的或安全的,则负责检查。 如果该请求是公开的终点,则允许通过。 然而,如果是安全的终点,则在允许请求通过之前,对一名JWT负责人进行严格审查。
我尝试了多种办法和执行,但我无法通过我的单位测试。 我怀疑这个问题可能与我的执行有关,但我不相信。
如果任何人能够就如何在微观服务结构中使用网上F奢侈品,正确写这一天云反应性预报网关的试验提供一些指导或想法,我将非常赞赏。
<>GatewayApplication.java:
package gateway;
import gateway.filters.*; // simplified the import all the filter once (AuthAccountFilter included)
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.server.handler.DefaultWebFilterChain;
@SpringBootApplication(exclude = { ErrorMvcAutoConfiguration.class })
@EnableEurekaClient
@CrossOrigin(origins = "*", allowedHeaders = "*")
@EnableDiscoveryClient
@EnableHystrix
public class GatewayApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder rlb, AuthAccountFilter authAccountFilter) {
return rlb
.routes()
.route(p -> p
.path("/my-service/**")
.filters(f -> f
.rewritePath("/my-service/(?<segment>.*)", "/$\{segment}")
.filter(authAccountFilter.apply(new AuthAccountFilter.Config())))
.uri("lb://MY-SERVICE"))
.build();
}
@Override
public void run(String... args) throws Exception {
System.out.println("... My-Service is UP -- READY TO GO!");
}
}
<>AuthAccountFilter.java:
package gateway.filters;
import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.shaded.json.JSONObject;
import com.nimbusds.jwt.JWTClaimsSet;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ResponseStatusException;
import reactor.core.publisher.Mono;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
@Component
public class AuthAccountFilter extends AbstractGatewayFilterFactory<AuthAccountFilter.Config> {
private Logger LOGGER = LoggerFactory.getLogger(AuthAccountFilter.class);
@Autowired
WebClient.Builder webClientBuilder;
@Override
public Class<Config> getConfigClass() {
return Config.class;
}
public static class Config {
// empty class as I don t need any particular configuration
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
String endpoint = exchange.getRequest().getPath().toString();
LOGGER.trace("Gateway filter for endpoint : " + endpoint);
LOGGER.info("Checking permission for endpoint : " + endpoint);
if (exchange.getRequest().getPath().toString().contains("auth") ||
exchange.getRequest().getPath().toString().contains("otp") ||
exchange.getRequest().getPath().toString().toLowerCase().contains("reset-password")) {
LOGGER.info("Public endpoint, aborting filter");
Mono<Void> filter = chain.filter(exchange);
System.err.println(filter == null);
return filter;
}
};
}
}
<>AuthAccountFilter Test.java:
package gateway.filters;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.MockServerHttpResponse;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import reactor.core.CoreSubscriber;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(SpringRunner.class)
class AuthAccountFilterTest {
private GatewayFilterChain filterChain = mock(GatewayFilterChain.class);
@Test
void testPublicEndpoint() {
String baseUrl = "http://localhost:9090/my-service/";
// Create a mock request and response
MockServerHttpRequest request = MockServerHttpRequest.get(baseUrl + "auth").build();
MockServerHttpResponse response = new MockServerHttpResponse();
// Create an instance of your AuthFilter and any dependencies it has
AuthAccountFilter filter = new AuthAccountFilter();
WebFilterChain chain = (exchange, filterChain) -> {
// Set the Config instance on the Exchange object
AuthAccountFilter.Config config = new AuthAccountFilter.Config();
exchange.getAttributes().put("config", config);
// Call the apply method of the AuthFilter, passing in the Config instance
return filter.apply(config);
};
}
}
事先感谢你提供任何帮助。