我在设置 spring 安全性和禁用/启用对经过 jwt 身份验证的基于角色的用户的 graphql
服务访问时遇到问题。所有其他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();
}
}
在启用 JWTlocalhost:8080/login
并发送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
}