You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否从ServerWebExchange中获取当前用户的角色信息?

从ServerWebExchange获取用户角色信息

当然可以获取用户角色,下面是几种可行的实现方式:

1. 类型转换获取角色

如果你的Principal实例实际是UserDetails(或自定义的用户信息类,实现了UserDetails或携带角色字段),可以直接强转后获取权限/角色:

exchange.getPrincipal()
        .filter(principal -> principal instanceof UserDetails)
        .cast(UserDetails.class)
        .subscribe(userDetails -> {
            // 获取用户角色/权限集合
            Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
            // 编写你的处理逻辑
        });

2. 通过ReactiveSecurityContextHolder获取

在Spring WebFlux环境下,更推荐从ReactiveSecurityContextHolder获取包含完整权限信息的Authentication对象:

return ReactiveSecurityContextHolder.getContext()
        .map(SecurityContext::getAuthentication)
        .flatMap(authentication -> {
            // 获取用户角色/权限
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            // 根据角色修改请求示例
            ServerHttpRequest modifiedRequest = exchange.getRequest()
                    .mutate()
                    .header("X-User-Roles", authorities.stream()
                            .map(GrantedAuthority::getAuthority)
                            .collect(Collectors.joining(",")))
                    .build();
            ServerWebExchange modifiedExchange = exchange.mutate().request(modifiedRequest).build();
            // 继续执行过滤链
            return chain.filter(modifiedExchange);
        });

3. 自定义Principal对象(适用于自定义认证场景)

如果是自己实现的认证逻辑,可以让自定义的Principal类直接携带角色信息,比如:

public class CustomPrincipal implements Principal {
    private String name;
    private List<String> roles;

    // 构造方法、getName()实现
    @Override
    public String getName() {
        return name;
    }

    // 获取角色的方法
    public List<String> getRoles() {
        return roles;
    }
}

之后在代码中直接转换获取:

exchange.getPrincipal()
        .cast(CustomPrincipal.class)
        .subscribe(principal -> {
            List<String> roles = principal.getRoles();
            // 编写你的处理逻辑
        });

GatewayFilter完整示例

结合你的场景,下面是一个根据用户角色修改请求的GatewayFilter实现:

public class RoleBasedFilter implements GatewayFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return ReactiveSecurityContextHolder.getContext()
                .map(SecurityContext::getAuthentication)
                .map(auth -> {
                    boolean hasAdminRole = auth.getAuthorities().stream()
                            .anyMatch(authz -> authz.getAuthority().equals("ROLE_ADMIN"));
                    if (hasAdminRole) {
                        // 管理员角色添加特殊请求头
                        return exchange.getRequest().mutate()
                                .header("X-Admin-Access", "true")
                                .build();
                    } else {
                        // 普通用户使用原请求
                        return exchange.getRequest();
                    }
                })
                .map(modifiedRequest -> exchange.mutate().request(modifiedRequest).build())
                .flatMap(chain::filter);
    }
}

内容的提问来源于stack exchange,提问作者Sergey Zolotarev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 11:37:19