aerogear / keycloak-connect-graphql

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

type-graphql #83

Closed sgentile closed 4 years ago

sgentile commented 4 years ago

Anyone using this with type-graphql ?

wtrocki commented 4 years ago

From my understanding type graphql will generate schema so some special handling is needed on typegraphql side. Our team also maintains https://graphback.dev and hoping to add it there. With typegraphql we can still use auth in the code.

justinlevi commented 4 years ago

Would love to see this as well

On Thu, Apr 30, 2020 at 4:37 AM Wojtek Trocki notifications@github.com wrote:

From my understanding type graphql will generate schema so some special handling. Our team also maintains https://graphback.dev and hoping to add it there.

With typegraphql we can still use auth in the code.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/aerogear/keycloak-connect-graphql/issues/83#issuecomment-621696054, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIQ6JKXTURXWENUW4S2XBLRPE2ENANCNFSM4MUDRL3A .

darahayes commented 4 years ago

Thanks for opening this issue. I'm not deeply familiar with type-graphql but I looked through their documentation on how they handle authorization and it should be possible. The caveat is that this library is only currently tested with Express. If you're using express + type-graphql it should be possible.

Based on their docs they have this @Authorized annotation. Example:

@Resolver()
class MyResolver {
  @Query()
  publicQuery(): MyObject {
    return {
      publicField: "Some public data",
      authorizedField: "Data for logged users only",
      adminField: "Top secret info for admin",
    };
  }

  @Authorized()
  @Query()
  authedQuery(): string {
    return "Authorized users only!";
  }

  @Authorized("ADMIN", "MODERATOR")
  @Mutation()
  adminMutation(): string {
    return "You are an admin/moderator, you can safely drop the database ;)";
  }
}

and then as a user you implement the authChecker option that gets passed to buildSchema.

import { customAuthChecker } from "../auth/custom-auth-checker.ts";

const schema = await buildSchema({
  resolvers: [MyResolver],
  // here we register the auth checking function
  // or defining it inline
  authChecker: keycloakAuthChecker,
});

Assuming you followed the setup instructions for this project and you added the KeycloakContext to the resolver context:

const server = new ApolloServer({
  typeDefs: [KeycloakTypeDefs, typeDefs], // 1. Add the Keycloak Type Defs
  schemaDirectives: KeycloakSchemaDirectives, // 2. Add the KeycloakSchemaDirectives
  resolvers,
  context: ({ req }) => {
    return {
      kauth: new KeycloakContext({ req }) // 3. add the KeycloakContext to `kauth`
    }
  }
})

(this example is for apollo server but you could also add it to the context in other implementations like graphql-express)

Then you should be able to implement an AuthChecker that will be compatible with type-graphql. I haven't tested this but it might look something like this:

export const keycloakAuthChecker: AuthChecker<ContextType> = (
  { root, args, context, info },
  roles,
) => {
  // here we can read the user from context
  // and check his permission in the db against the `roles` argument
  // that comes from the `@Authorized` decorator, eg. ["ADMIN", "MODERATOR"]

  if (!context.kauth.isAuthenticated()) {
    return false; // user not logged in
  }

  if (roles && roles.length > 0) {
    if (!roles.some(context.kauth.hasRole) {
      return false // user did not have at least one role
    }
  }
  return true // user is logged in and has at least one role
};

I haven't actually tested this code out but you should be able to experiment with it and get a result. Please get back to us and let us know. If it does work we could officially provide an AuthChecker Implementation.

sgentile commented 4 years ago

We ended up just using keycloak-connect and setup the typed-graphql solution through their Authorized attribute.

Thanks

On Thu, Apr 30, 2020, 6:40 AM Justin Levi Winter notifications@github.com wrote:

Would love to see this as well

On Thu, Apr 30, 2020 at 4:37 AM Wojtek Trocki notifications@github.com wrote:

From my understanding type graphql will generate schema so some special handling. Our team also maintains https://graphback.dev and hoping to add it there.

With typegraphql we can still use auth in the code.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub < https://github.com/aerogear/keycloak-connect-graphql/issues/83#issuecomment-621696054 , or unsubscribe < https://github.com/notifications/unsubscribe-auth/AAIQ6JKXTURXWENUW4S2XBLRPE2ENANCNFSM4MUDRL3A

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/aerogear/keycloak-connect-graphql/issues/83#issuecomment-621754420, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABAKNE7ZGMXLHHHCFWRA4LRPFITHANCNFSM4MUDRL3A .

darahayes commented 4 years ago

Yeah that works perfectly fine too! In this case keycloak-connect-graphql can be used but not really needed.