aerogear / keycloak-connect-graphql

Add Keyloak Authentication and Authorization to your GraphQL server.
Apache License 2.0
155 stars 22 forks source link

KeycloakContext does not retrieve the AccessToken #54

Closed jdc18 closed 4 years ago

jdc18 commented 4 years ago

I did some test with an old version of keycloak 3.4.1.Final with keycloak-connect-graphql and it was working and then I decided to update the keycloak version to the latest version 8.0.1, and I had a lot of issues that I managed to solve both on the client and the server, but for some reason I cannot get the access token on my server. On my server I have this


const server = new ApolloServer({ 
  typeDefs: [KeycloakTypeDefs, typeDefs], 
  schemaDirectives: KeycloakSchemaDirectives,
  cors: cors(corsOptions),
  resolvers, 
  context: ({ req }) => {
    const token = req.headers.authorization || '';
    console.log(`Token: ${token}`);
    return { kauth: new KeycloakContext({ req }) };
  }
});

Here on the console.log i see something like the following image So I do get the header authorization. But in my resolvers,

Query: {
        getCurrentUser: async (root, args, { kauth }, info) => {
            console.log("Get Current User");
            console.log(kauth);
            console.log(kauth.accessToken);
          .....
        }
    }

Here kauth.accessToken I get undefined. But when I print just kauth I do see it on the request image On the headers I do see the token on the info but the AccessToken is set to undefined.

wtrocki commented 4 years ago

Hi

In recent version keycloak might have changed the way they attach token to request. This library is using following method:

https://github.com/aerogear/keycloak-connect-graphql/blob/master/src/KeycloakContext.ts#L73

It looks like req.kauth might be undefined. Can you do me a fav and print it out for us to make sure it is undefined

Edit: Looks like there were no change in keycloak library. I cannot reproduce this problem on example app.

https://github.com/keycloak/keycloak-nodejs-connect/blob/4d26c24d36d2f96f9c39f057291a03a4e26bc2bf/middleware/auth-utils/grant-manager.js#L129

Our lib uses latest available version https://github.com/aerogear/keycloak-connect-graphql/blob/master/package.json#L39

wtrocki commented 4 years ago

So I think that we might simply miss keycloak middleware on graphql endpoint. Headers will have token but it is not transformed into actual token instance by keycloak middleware. Let me know if that was it

If it still exist we could try to replicate this issue on sample app that will be really helpful as we can fix that instantly

jdc18 commented 4 years ago

Hi, You are right , it seems to be a problem with the middleware. When I do a console.log(req.kauth), I get "{}" a so there is obviously no req.kauth.grant. I am going to check if my tokens are correctly. I know this is probably outside your scope, is there anything wrong with how I declared my middleware?

const app = express();

const memoryStore = new session.MemoryStore();

//app.use(bodyParser.json());

app.use(session({
  secret: process.env.SESSION_SECRET_STRING || 'zzzzzz',
  resave: false,

  saveUninitialized: true,
  store: memoryStore
}))

const keycloak = new Keycloak({
  store: memoryStore
});

app.use('/graphql',keycloak.middleware());

const corsOptions = {
  origin: 'http://localhost:3000',
  credentials: true
}

const server = new ApolloServer({ 
  typeDefs: [KeycloakTypeDefs, typeDefs], 
  schemaDirectives: KeycloakSchemaDirectives,
  cors: cors(corsOptions),
  resolvers, 
  context: ({ req }) => {
    // get the user token from the headers
    const token = req.headers.authorization || '';
    console.log(req.kauth)
    console.log(`Token: ${token}`);
    return { kauth: new KeycloakContext({ req }) };
  }
});

server.applyMiddleware({ app });
wtrocki commented 4 years ago

Req.kauth is not undefined so we could have many problems here. I would debug if keycloak middleware is used and check why grant is not attached.

I would also comment out code that setup session and cors as they might affect some things.

wtrocki commented 4 years ago

Closing. Feel free to reopen if neeed.

jdc18 commented 4 years ago

Thanks I finally solved it The problem is that keycloak8.0.1 it generates the json file with an slash at the end, "auth-server-url": "http://localhost:8180/auth/", I took the / at the end because the realm was giving me invalid token (wrong ISS). Anyways thanks for your time.

darahayes commented 4 years ago

@jdc18 Glad to hear you figured out the issue. We have also come across this trailing slash bug before. Sorry we didn't help you find it a bit quicker. There was a PR to fix it in the official keycloak-connect module but the changes haven't been released yet.

harrylepotter-win commented 3 years ago

You may also want to check on "verify-token-audience" in your keycloak config (.json?) - if you dont have an appropriate resource, it will cause the access_token to not be visible by the keycloak middleware