求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
相关产品推荐
相关产品推荐

