cancel
Showing results for 
Search instead for 
Did you mean: 

isAuthenticated directive ignored in Apollo Federated Gateway schema

bokjo
Node

Hello everybody,

This morning I created this issue on GitHub regarding the Authentication directive being ignored for GraphQL Grand stack federated augmented schema called through the Gateway.

In short:

  1. running the Apollo GraphQL Server directly with the augmented schema the @isAuthenticated directive works as expected

  2. running the Apollo GraphQL Server with federated schema based on the augmented one and calling the API through the Gateway doesn't work and the @isAuthenticated directive is not respected (you can call the API without providing JWT into the Authorization header )

p.s same behaviour if you call the API directly and not via the Gateway

For more details and code examples please refer to the GitHub issue above.

Any general input on this and how to debug it is more than welcome.

Thank you
Bojanche S.

4 REPLIES 4

uday
Node Link

Here is a snipper I have. I need my API to be used always when authorised. So connection to database can be established only when there is a valid JWT

  1. Starting the Apollo server -Snippet
const server = new ApolloServer({
  context: ({ req }) => {
    if(req.headers['user-agent'].startsWith('auth0-logstream')) {
      req.body.logs.forEach(log => {
        // authLogger.log(log);
      })
    }
    const realIp = req.headers['x-real-ip'];
    // logger.info({query: req.body.query, variables: req.body.variables, clientIp: realIp});
    
    /* 
      Order of operations - All must pass
      1. Decode Session Token
      2. Verify Session Token
      3. Get Email of the user
    */
    let sessionVerified = false;

    if(req.headers.authorization === undefined || req.headers.authorization === null) {
      // logger.error({'type':'unauthenticated', clientIp: realIp})
      throw new AuthenticationError('Unauthorized, Must Authenticate to access this resource.');
    }
    const decodedToken = jwt_decode(req.headers.authorization.replace('Bearer ', ''));
    
    const decoded = jwt.verify(req.headers.authorization.replace('Bearer ', ''), process.env.JWT_SECRET);
    if(decoded) {
      sessionVerified = true;
    }
// Locate the email thingy from JWT
 const email = decodedToken['https://authdomain.io/email'] ? decodedToken['https://authdomain.io/email'] : null;

if(email === null || email === undefined) {
throw new AuthenticationError("Oye mate, You're naughty.")
}

return {
      driver,
      // DB name on the server - using the email 
      neo4jDatabase: email.split('@')[1].replace('.', ''),
      headers: req.headers,
      token: req.headers.token,
      cypherParams: {
        variables: req.body.variables,
        email
      },
      req
    }
    
  },
  engine: {    
    reportSchema: true
  },
  schema: augmentedSchema,
  introspection: true,
  playground: false,
});


// Starting the server
server.listen(4000, '0.0.0.0')
.then(({ url }) => {
  console.log(\`🚀 GraphQL API is ready at ${url}\`);
})
.catch(err => {
  console.error('Failed to start server');
  console.error('--Details--');
  console.dir(err);
})%                
  1. Schema: Here is a sample schema for a Node where user can read or delete only. These are permissions that come from JWT. I hope this helps.
type Bojanche @hasScope(scopes: ["Bojanche: Read", "Bojanche: Delete"]) {
  id: ID @index
 name: String! @index
}

In my case, I am using Auth0 and starting a GrandStack with Auth0 is quite easy. I think what you are missing is using the hasScope directives and hasRoles directives.

Hello @uday

Thanks for the reply.

As I mentioned @isAuthenticared is working fine in the standalone API created with the augmented schema.

The problem comes when I convert the same augmentedSchema to a federated one in order to be used through Apollo Federation Gateway.

const schema = buildFederatedSchema([augmentedSchema]);

At this point calling the service directly or through the gateway ignores the @isAuthenticared, despite that the request is valid and can have or not the proper JWT.

Kind Regards,
Bojanche S.

@bokjo I actually took time to learn about Apollo Gateway. I do not have an answer for you as I have no clue mate.

Did you read this on grandstack? Using Apollo Federation and Gateway With Neo4j | GRANDstack