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

如何在Netflix DGS的查询中启用@AuthenticationPrincipal参数

让@AuthenticationPrincipal在Netflix DGS组件中生效的方法

问题根源

Netflix DGS的参数解析逻辑和Spring MVC REST控制器不共享,默认不会识别并处理Spring Security的@AuthenticationPrincipal注解,直接注入时自然返回null。

解决方案

1. 自定义DGS参数解析器(推荐)

实现DgsArgumentResolver接口,专门处理带@AuthenticationPrincipal注解的参数,让DGS框架自动识别并注入认证用户信息:

@Component
public class AuthenticationPrincipalArgumentResolver implements DgsArgumentResolver {

    @Override
    public boolean supportsParameter(Parameter parameter) {
        return parameter.isAnnotationPresent(AuthenticationPrincipal.class);
    }

    @Override
    public Object resolveArgument(Parameter parameter, DgsDataFetchingEnvironment environment) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !(authentication.getPrincipal() instanceof UserDetails)) {
            return null;
        }
        return authentication.getPrincipal();
    }
}

将该类注册为Spring组件后,所有DgsComponent中带@AuthenticationPrincipal的参数都会自动注入UserDetails实例。

2. 简化手动获取的封装(备选)

如果不想自定义解析器,可以在方法中结合注解和上下文手动兜底,保持代码风格一致:

@DgsComponent
public class YourGraphqlComponent {

    @DgsQuery
    public String getUserInfo(@AuthenticationPrincipal UserDetails userDetails) {
        if (userDetails == null) {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            userDetails = (UserDetails) auth.getPrincipal();
        }
        return userDetails.getUsername();
    }
}

3. 异步场景下的SecurityContext传播

如果你的GraphQL查询使用异步执行,需要确保SecurityContext能传递到异步线程:

@Configuration
@EnableAsync
public class AsyncSecurityConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("DgsAsync-");
        
        // 传播当前认证信息到异步线程
        executor.setTaskDecorator(runnable -> {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            return () -> {
                try {
                    SecurityContextHolder.getContext().setAuthentication(auth);
                    runnable.run();
                } finally {
                    SecurityContextHolder.clearContext();
                }
            };
        });
        executor.initialize();
        return executor;
    }
}

内容的提问来源于stack exchange,提问作者Denis Abakumov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 10:18:32