使用 RouteLocatorBuilder 授权 REST 调用
Authorizing the REST calls with RouteLocatorBuilder
背景
我的用例是使用网关对调用进行身份验证。我假设所有调用都必须有 user_id
和 token
。我有一个 API,在检查它是否是一个有效请求后,它会同时接受 user_id、令牌和 return 一个布尔值。
当前工作
我已经编写了一个网关配置,它在将 API 路由到相关 micro-service 时工作正常,但它在身份验证方面工作不正常。
工作代码,
@Configuration
public class RouteConfig {
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("app1/**")
.filters(f -> f.rewritePath("app1/(?<segment>.*)",
"app1/${segment}"))
.uri("http://localhost:8099"))
.build();
}
}
首先,我需要获取 Headers 变量,然后对 API 进行 POST 调用,其中 return 是 BOOLEAN 响应。如果它是真的那么上面的代码应该调用。否则呼叫应该被拒绝。
试图获得 Headers 值
@Configuration
public class RouteConfig {
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder,@RequestHeader("user_id")
String userId,@RequestHeader("token")
String token) {
System.out.println(userId);
System.out.println(token);
return builder.routes()
.route("path_route", r -> r.path("app1/**")
.filters(f -> f.rewritePath("app1/(?<segment>.*)",
"app1/${segment}"))
.uri("http://localhost:8099"))
.build();
}
}
但是它不工作并且应用程序崩溃了。
您可以实施 GatewayFilter
来检查网关上的每个请求。
@Component
public class AuthFilter implements GatewayFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
if (!headers.containsKey("user_id") || !headers.containsKey("token"))
return this.onError(exchange, HttpStatus.UNAUTHORIZED);
String userId = request.getHeaders().getOrEmpty("user_id").get(0);
String token = request.getHeaders().getOrEmpty("token").get(0);
Map<String, String> body = new HashMap<>();
body.put("user_id", userId);
body.put("token", token);
WebClient client = WebClient.builder().build();
boolean ok = client
.post()
.uri("your/auth/api")
.body(Mono.just(body), Map.class)
.retrieve()
.bodyToFlux(Boolean.class)
.blockFirst();
if (!ok)
return this.onError(exchange, HttpStatus.UNAUTHORIZED);
return chain.filter(exchange);
}
private Mono<Void> onError(ServerWebExchange exchange, HttpStatus httpStatus) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(httpStatus);
return response.setComplete();
}
}
并将过滤器应用于您的路线配置。不确定配置是否正确以及重写是否正确应用。
@Configuration
public class RouteConfig {
@Autowired
private AuthFilter filter;
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("app1/**")
.filters(f -> f.filters(filter).rewritePath("app1/(?<segment>.*)",
"app1/${segment}"))
.uri("http://localhost:8099"))
.build();
}
}
请注意,此代码未经测试,只是为了让您了解如何解决您的问题。
背景
我的用例是使用网关对调用进行身份验证。我假设所有调用都必须有 user_id
和 token
。我有一个 API,在检查它是否是一个有效请求后,它会同时接受 user_id、令牌和 return 一个布尔值。
当前工作
我已经编写了一个网关配置,它在将 API 路由到相关 micro-service 时工作正常,但它在身份验证方面工作不正常。
工作代码,
@Configuration
public class RouteConfig {
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("app1/**")
.filters(f -> f.rewritePath("app1/(?<segment>.*)",
"app1/${segment}"))
.uri("http://localhost:8099"))
.build();
}
}
首先,我需要获取 Headers 变量,然后对 API 进行 POST 调用,其中 return 是 BOOLEAN 响应。如果它是真的那么上面的代码应该调用。否则呼叫应该被拒绝。
试图获得 Headers 值
@Configuration
public class RouteConfig {
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder,@RequestHeader("user_id")
String userId,@RequestHeader("token")
String token) {
System.out.println(userId);
System.out.println(token);
return builder.routes()
.route("path_route", r -> r.path("app1/**")
.filters(f -> f.rewritePath("app1/(?<segment>.*)",
"app1/${segment}"))
.uri("http://localhost:8099"))
.build();
}
}
但是它不工作并且应用程序崩溃了。
您可以实施 GatewayFilter
来检查网关上的每个请求。
@Component
public class AuthFilter implements GatewayFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
if (!headers.containsKey("user_id") || !headers.containsKey("token"))
return this.onError(exchange, HttpStatus.UNAUTHORIZED);
String userId = request.getHeaders().getOrEmpty("user_id").get(0);
String token = request.getHeaders().getOrEmpty("token").get(0);
Map<String, String> body = new HashMap<>();
body.put("user_id", userId);
body.put("token", token);
WebClient client = WebClient.builder().build();
boolean ok = client
.post()
.uri("your/auth/api")
.body(Mono.just(body), Map.class)
.retrieve()
.bodyToFlux(Boolean.class)
.blockFirst();
if (!ok)
return this.onError(exchange, HttpStatus.UNAUTHORIZED);
return chain.filter(exchange);
}
private Mono<Void> onError(ServerWebExchange exchange, HttpStatus httpStatus) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(httpStatus);
return response.setComplete();
}
}
并将过滤器应用于您的路线配置。不确定配置是否正确以及重写是否正确应用。
@Configuration
public class RouteConfig {
@Autowired
private AuthFilter filter;
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("app1/**")
.filters(f -> f.filters(filter).rewritePath("app1/(?<segment>.*)",
"app1/${segment}"))
.uri("http://localhost:8099"))
.build();
}
}
请注意,此代码未经测试,只是为了让您了解如何解决您的问题。