【问题标题】:GraphQL Spring AccessDeniedException HandlingGraphQL Spring AccessDeniedException 处理
【发布时间】:2020-05-16 10:48:37
【问题描述】:

我正在为我的解析器类使用注释“@PreAuthorize”,因此我得到了 AccessDeniedException。这就是我想要的,但它被扔到服务器上的我的日志控制台。 我尝试了很多方法来摆脱这个错误并以某种方式处理它,只是为了打印一行,例如“未经授权的尝试”,而不是整个堆栈跟踪。你知道我应该在哪里处理它吗?

2020-05-16 12:21:27.026  WARN 12308 --- [0.1-1100-exec-1] g.e.SimpleDataFetcherExceptionHandler    : Exception while fetching data (/somePath) : Access is denied

org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.6.RELEASE.jar:5.1.6.RELEASE]```

【问题讨论】:

    标签: spring spring-boot authentication exception graphql


    【解决方案1】:

    您可以提供自己的 AsyncExecutionStrategy 扩展,然后使用自己的 DataFetchingExceptionHandler 构造它,如下所示:

    @Component
    public class QueryExecutionStrategy extends AsyncExecutionStrategy {
        public QueryExecutionStrategy() {
            super(new GraphQLExceptionHandler());
        }
    
        @Override
        public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext,
                                                          ExecutionStrategyParameters parameters)
                throws NonNullableFieldWasNullException {
            return super.execute(executionContext, parameters);
        }
    }
    

    虽然 ExceptionHandler 可能看起来像这样:

    public class GraphQLExceptionHandler implements DataFetcherExceptionHandler {
        private final Logger log = LoggerFactory.getLogger(GraphQLExceptionHandler.class);
    
        @Override
        public DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters) {
            Throwable exception = handlerParameters.getException();
            SourceLocation sourceLocation = handlerParameters.getSourceLocation();
            ExecutionPath path = handlerParameters.getPath();
            if (exception instanceof AccessDeniedException) {
                log.warn("unauthorized to access " +
                            path);
            }
            ExceptionWhileDataFetching error = new ExceptionWhileDataFetching(path, exception, sourceLocation);
            log.warn(error.getMessage(), exception);
            return DataFetcherExceptionHandlerResult.newResult().error(error).build();
        }
    }
    

    您还可以通过返回 DataFetcherExceptionHandlerResult 来完全禁用报告给客户端的任何错误,而不在 if 语句中附加任何错误。

    【讨论】:

    • 现在我可以看到我正在处理它,因为日志来自我自己的 DataFetcherExceptionHandler 但 AsyncExecutionStrategy 仍然会产生堆栈跟踪错误`QueryExecutionStrategy.execute(QueryExecutionStrategy.java:22) ~[classes/: na] ` 我应该在那儿抓住这个吗?或者它不应该在那里发生?
    • 我试过没有你提到的附加子句错误,它仍然产生错误。
    • 好的 nvm,我之前一定是做错了。现在我按照你所说的在 if 语句中返回空的 DataFetcherExceptionHandlerResult 并且它工作得很好。非常感谢你:)
    • 好吧,似乎创建 ExceptionWhileDataFetching 会导致错误,因为当我在 return 语句中删除子句 .error(error) 时,它仍然会在服务器日志中产生错误。你能解释一下或链接我它是如何工作的吗?
    • 我们正在这样做,它对我们有用:return DataFetcherExceptionHandlerResult.newResult().build();。我们使用的是最新版本的 graphql-java 和 graphql-spring-boot
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 2013-11-01
    • 1970-01-01
    • 2017-06-14
    • 2013-04-10
    • 2013-01-03
    • 1970-01-01
    相关资源
    最近更新 更多