Spring Cloud Security配置JWT和OAuth2的集成实现授权管理(三)

2023-04-14 07:47:11 浏览数 (3)

编写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令牌添加到请求标头中。如果找不到已授权的客户端,则继续处理请求。

0 人点赞