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

求Spring Security整合GraphQL-SPQR的角色权限实现示例及报错解决

GraphQL-SPQR + Spring Security 角色认证授权实现及Playground错误修复

一、依赖配置

首先确保项目依赖中包含必要组件:

Maven(pom.xml)

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>io.leangen.graphql</groupId>
        <artifactId>graphql-spqr-spring-boot-starter</artifactId>
        <version>0.12.0</version> <!-- 替换为最新稳定版 -->
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

Gradle(build.gradle)

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'io.leangen.graphql:graphql-spqr-spring-boot-starter:0.12.0'
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

二、Spring Security 核心配置

配置安全规则,适配GraphQL Playground访问需求,同时开启角色认证:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // 关闭CSRF防护,解决Playground POST请求被拦截问题
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(auth -> auth
                // 允许Playground及相关静态资源免认证访问
                .requestMatchers("/playground", "/graphiql", "/vendor/**").permitAll()
                // 所有GraphQL接口请求必须经过认证
                .requestMatchers("/graphql").authenticated()
            )
            // 启用HTTP Basic认证,方便Playground测试
            .httpBasic(Customizer.withDefaults());

        return http.build();
    }

    // 内存用户示例(生产环境建议替换为数据库查询逻辑)
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails admin = User.withUsername("admin")
            .password("{noop}admin123") // {noop}表示明文密码,仅测试用,生产需用BCrypt等加密方式
            .roles("ADMIN")
            .build();
        UserDetails user = User.withUsername("user")
            .password("{noop}user123")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(admin, user);
    }
}

三、GraphQL-SPQR 接口权限控制

在GraphQL服务方法上使用Spring Security的@PreAuthorize注解实现角色级授权:

@Component
public class UserGraphQLService {

    // 仅ADMIN角色可调用该查询
    @GraphQLQuery(name = "getAllUsers")
    @PreAuthorize("hasRole('ADMIN')")
    public List<User> getAllUsers() {
        // 模拟业务逻辑,返回用户列表
        return Arrays.asList(
            new User(1, "admin"),
            new User(2, "user")
        );
    }

    // USER或ADMIN角色均可调用该查询
    @GraphQLQuery(name = "getCurrentUser")
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public User getCurrentUser(Authentication authentication) {
        return new User(0, authentication.getName());
    }
}

// 简单User实体类
@Data
@AllArgsConstructor
public class User {
    private Integer id;
    private String username;
}

四、修复Playground "Unexpected end of JSON input" 错误

该错误源于请求被Spring Security拦截导致返回空内容,JSON解析失败,按以下步骤修复:

  • 确认CSRF已关闭:上述配置中已添加csrf.disable(),若未关闭,Playground的POST请求会被拦截。
  • 添加认证请求头:在Playground的HTTP HEADERS面板中添加Basic认证信息,示例:
    {
      "Authorization": "Basic YWRtaW46YWRtaW4xMjM="
    }
    
    (注:YWRtaW46YWRtaW4xMjM=是admin:admin123的Base64编码,可自行生成对应账号的编码)
  • 验证端点URL:确保Playground中配置的GraphQL端点与项目一致(默认是/graphql)。

内容的提问来源于stack exchange,提问作者Amit Jolly

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:35:07