编写JwtTokenFilter和JwtAuthenticationFilter
为了使用JWT和OAuth2进行授权管理,我们需要编写两个过滤器:JwtTokenFilter和JwtAuthenticationFilter。
JwtTokenFilter用于提取和验证JWT令牌:
代码语言:javascript复制public class JwtTokenFilter implements GatewayFilter {
private final ReactiveJwtDecoder jwtDecoder;
public JwtTokenFilter(ReactiveJwtDecoder jwtDecoder) {
this.jwtDecoder = jwtDecoder;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String authorizationHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
String token = authorizationHeader.substring(7);
return jwtDecoder.decode(token)
.flatMap(jwt -> {
exchange.getRequest().mutate()
.header("X-User-Id", jwt.getSubject())
.header("X-User-Roles", jwt.getClaimAsStringList("roles"))
.build();
return chain.filter(exchange);
})
.onErrorResume(e -> chain.filter(exchange));
}
return chain.filter(exchange);
}
}
在上面的代码中,我们使用ReactiveJwtDecoder接口来解码JWT令牌,并使用filter方法来提取和验证JWT令牌。如果JWT令牌有效,则将用户ID和角色添加到请求标头中。否则,我们将继续处理请求。
JwtAuthenticationFilter用于验证OAuth2授权并将OAuth2令牌添加到请求标头中:
代码语言:javascript复制public class JwtAuthenticationFilter extends AbstractGatewayFilterFactory<JwtAuthenticationFilter.Config> {
private final ReactiveOAuth2AuthorizedClientService authorizedClientService;
public JwtAuthenticationFilter(ReactiveOAuth2AuthorizedClientService authorizedClientService) {
super(Config.class);
this.authorizedClientService = authorizedClientService;
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
return exchange.getPrincipal()
.cast(OAuth2AuthenticationToken.class)
.flatMap(authentication -> authorizedClientService.loadAuthorizedClient(
authentication.getAuthorizedClientRegistrationId(),
authentication.getName())
.flatMap(authorizedClient -> {
exchange.getRequest().mutate()
.header(HttpHeaders.AUTHORIZATION,
"Bearer " authorizedClient.getAccessToken().getTokenValue())
.build();
return chain.filter(exchange);
})
.switchIfEmpty(chain.filter(exchange)));
};
}
public static class Config {}
}
在上面的代码中,我们使用ReactiveOAuth2AuthorizedClientService接口来获取已授权的OAuth2客户端,并使用filter方法将OAuth2令牌添加到请求标头中。如果找不到已授权的客户端,则继续处理请求。