我在为graphql
服务设置Spring Security 和禁用/启用对jwt身份验证的基于角色的用户的访问时遇到问题。所有其他REST
终结点都得到了正确保护,并且JWT
身份验证和基于角色的授权工作正常。
目前为止我所拥有的:
在我的WebSecurityConfigurerAdapter
类中,我有以下代码:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors()
.and()
.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "**/student-service/auth/**").permitAll().antMatchers("**/student-service/auth/**").authenticated()
.and()
.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "**/graphql/**").permitAll().antMatchers("**/graphql/**").authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(entryPoint).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http.headers().cacheControl();
}
在graphql
服务上,我有一个@PreAuthorize
:
@Component
public class UserResolver implements GraphQLQueryResolver{
@Autowired
UserRepo repo;
@PreAuthorize("hasAnyAuthority('ADMIN')")
public User findUser(int id) {
return User.builder()
.id(1)
.email("test@grr.la")
.password("123")
.username("John")
.bankAccount(BankAccount.builder()
.id(1)
.accountName("some account name")
.accountNumber("some account number")
.build())
.build();
}
}
在localhost:8080/login
上获取JWT并发送graphql
查询后,使用上面的配置和代码,我得到了:
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:73) ~[spring-security-core-5.4.5.jar:5.4.5]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.attemptAuthorization(AbstractSecurityInterceptor.java:238) ~[spring-security-core-5.4.5.jar:5.4.5]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:208) ~[spring-security-core-5.4.5.jar:5.4.5]
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:58) ~[spring-security-core-5.4.5.jar:5.4.5]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.5.jar:5.3.5]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.5.jar:5.3.5]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) ~[spring-aop-5.3.5.jar:5.3.5]
以下是来自Postman
的请求的外观:
GraphQL查询:
query {
findUser(id : 1) {
id
email
}
}
并回应:
{
"errors": [
{
"message": "Access is denied",
"locations": [
{
"line": 2,
"column": 1
}
],
"path": [
"findUser"
],
"extensions": {
"type": "AccessDeniedException",
"classification": "DataFetchingException"
}
}
],
"data": {
"findUser": null
}
}
application.yml
文件:
graphql:
servlet:
max-query-depth: 100
exception-handlers-enabled: true
playground:
headers:
Authorization: Bearer TOKEN
query.graphqls
文件:
type Query {
findUser(id: ID): User
}
type User {
id: ID!
username: String
password: String
email: String
bankAccount: BankAccount
}
type BankAccount {
id: ID!
accountName: String
accountNumber: String
}
1条答案
按热度按时间qaxu7uf21#
我花了一天的时间试图弄明白这一点。
您应该返回一个 GraphQLContext 的示例,它包含HTTP请求和带有授权的头。对我来说,这实际上是一个空的 HashMap,没有关于请求的任何细节。在挖掘并尝试AOP更改的所有内容之后,我发现auth0建议创建一个实现 GraphQLInvocation 的类。下面是我的解决方案,它将SpringSecurity上下文的一个示例放置到数据获取环境上下文对象中。(具有授权等)。我更希望有一个与Spring Security集成的过滤器(我可以像您一样使用preAuthorize方法),但目前我正在使用这个方法。