我的体系结构中有几个微服务。我想实现一个API网关来路由请求到服务。为了实现这个,我实现了spring-cloud-gateway
这是我的application.yml
server:
port: 9090
spring:
application:
name: "API-GATEWAY"
cloud:
gateway:
routes:
- id: task-service
uri: 'http://localhost:8083'
predicates:
- Path=/task/**
到目前为止一切正常。请求localhost:9090/task/123
到localhost:8083/task/123
。下面是第二部分。
我希望某些用户只能访问某些端点。在我的JWT令牌中,我有一个角色字段。
{
"accountName": "erdem.ontas",
"surname": "Öntaş",
"roles": [
"ADMIN",
"USER"
],
}
我不想在每个服务中单独指定授权,有没有办法在spring-cloud-gateway中指定基于角色的访问?例如,我希望USER角色能够访问GET http://localhost:9090/task/
,但不能访问GET http://localhost:9090/dashboard/
not想要并且需要创建完整的OAuth 2服务器/客户端基础设施,并希望保持简单,只需创建一个自定义GatewayFilter
,其中只需检查从标头提取的JWT令牌是否具有预配置的角色。所以从一个简单的GatewayFilter
@Component
public class RoleAuthGatewayFilterFactory extends
AbstractGatewayFilterFactory<RoleAuthGatewayFilterFactory.Config> {
public RoleAuthGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
var request = exchange.getRequest();
// JWTUtil can extract the token from the request, parse it and verify if the given role is available
if(!JWTUtil.hasRole(request, config.getRole())){
// seems we miss the auth token
var response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
return chain.filter(exchange);
};
}
@Data
public static class Config {
private String role;
}
@Override
public List<String> shortcutFieldOrder() {
// we need this to use shortcuts in the application.yml
return Arrays.asList("role");
}
}
这里我们只是创建了一个简单的过滤器,它从配置(application.yml)中接收所需的角色,并检查请求是否被授权继续。
要使用过滤器,只需将filters
添加到路由配置中。
server:
port: 9090
spring:
application:
name: "API-GATEWAY"
cloud:
gateway:
routes:
- id: task-service
uri: 'http://localhost:8083'
filters:
- RoleAuth=ADMIN
predicates:
- Path=/task/**
这样,RoleAuth
过滤器可以在多条路由上重复使用。