I have a pretty standard Spring Boot application that I just started with Spring Security using JWT. I’ve added in the spring boot start GraphQL support (which I’ve done on a non-secured app in the past) and it works fine. However, I’m struggling to find a solution on how to allow access to /graphicl
that will work correctly since the call to instrospect the schema is to the /graphql
route which I have locked down since that’s the route that all my data calls are made on to the resolvers.
I’ve tried a couple of different filters and applied them to the security filter chain like so..
.addFilterBefore(new IntrospectionQueryFilter(), usernamePasswordAuthenticationFilter.class)
public class IntrospectionQueryFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// No initialization needed
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
final var method = httpRequest.getMethod();
final var uri = httpRequest.getRequestURI();
if (isIntrospectionQuery(httpRequest)) {
chain.doFilter(request, response);
} else {
// Proceed to authentication
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}
private boolean isIntrospectionQuery(HttpServletRequest request) throws IOException {
final var method = request.getMethod();
final var uri = request.getRequestURI();
if (uri.equals("/graphiql") || uri.equals("/favicon.ico")) {
return true;
}
if ("POST".equalsIgnoreCase(request.getMethod()) && "/graphql".equalsIgnoreCase(request.getRequestURI())) {
BufferedReader reader = request.getReader();
StringBuilder body = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
body.append(line);
}
return body.toString().contains(""operationName":"IntrospectionQuery"");
}
return false;
}
@Override
public void destroy() {
// No resources to clean up
}
But this doesn’t seem to work. I can’t find a way to customize the introspection call so that it’s on a non-secured route other than /graphql
.