Is your feature request related to a problem? Please describe.
I'm frustrated when I need to defined a BIG AuthChecker and I need a graphql-shield-like approch to protect my resolvers.
Describe the solution you'd like
Make the Authorized decorator to accept graphql-shield rules and generate appropriate permission tree then apply it to the schema.
Just like this:

Describe alternatives you've considered
Here is my workaround approach, but I really hope that there would be a better official approach to model the authentication layer in type-graphql.
Additional context
No additional context so far.
Have you tried to use just @UseMiddleware for that? It has the same signature as graphql-middleware so you should be able to use graphql-shield easily. @Authorized is just a middleware that use the metadata provided on the field/resolver method, if you don't like this approach you can use your own with middlewares and custom decorators.
Well, this is a good idea, and can be done by @UseMiddleware with rules apply in runtime. But my point is that the current @Authorized(roles)&authChecker(func) style authentication is not enough for many situations. And if we consider authentication a part of type-graphql, maybe we should achieve it with a better approach, such as graphql-shield. How do you like it? 馃槈
style authentication is not enough for many situations
Could you elaborate on why you think it's not enough?
Imaging that we have a resource that only available for users not only with role of admin but also another single user or two.
And I prefer the model of RBAC, with concepts of user, role and permission.

And with graphql-shield, we can achieve it.
But the bulti-in authorization module is not only about the string roles. It's basically storing the metadata you want by calling @Authorized<YourType>() - it can be objects (ACL) or a functions (dynamic rules) too. And a generic auth handler that will receive the resolver data, the metadata from decorator and can calculate the access.
GraphQL shield API is strictly for applying the guard rules on apollo-like resolvers when we have typedefs defined as sdl string. So there's no need for making a wrapper on a wrapper for authorization.
hmm...I finally realized...I just got caught into the naming of role and its default implementation of string...Maybe we should change the name of role to permissionIdentifier or some what? or comment it in the docs? Just in case of stupid guys like me. 馃槶
Just always read the docs first - TypeScript definitions are not enough to work with all te features of the new framework 馃槈
We can leave the
@Authorizeddecorator brackets empty or we can specify the role/roles that the user needs to possess in order to get access to the field, query or mutation. By default the roles are of type string but they can easily be changed as the decorator is generic -@Authorized<number>(1, 7, 22).
https://typegraphql.ml/docs/authorization.html#how-to-use
In the future when #124 comes to live, I will refactor the authorization feature to use it and add an example/tutorial in docs how to create your own authorization layer with custom logic. So closing this issue for now 馃敀
Does anyone have a working example of using graphql-shield rules in type-graphql, either using @Authorized<IRule> or by applying shield as a global middleware and using custom rule decorators? I've been trying to make it work with the first approach, but am having issues with resolving the rules from within the auth checker.
@MichalLytek Having an example would really help, one advantage of shield is the caching so you don't execute complex checks multiple times.
@snys98 @Sytten @Nevon
// permissions.ts
import { shield, allow, or, and, deny } from 'graphql-shield';
export default shield(
{
Query: {
abuses: deny,
},
},
{ debug: true },
);
// index.ts
import { applyMiddleware } from 'graphql-middleware';
const schema = await tq.buildSchema({
resolvers,
});
const context = createContext();
const server = new ApolloServer({
schema: applyMiddleware(schema, permissions),
context,
validationRules,
formatError,
});
server.listen({ port: 4000 }, () => console.log('馃殌 Server ready at: http://localhost:4000' );
Most helpful comment
@MichalLytek Having an example would really help, one advantage of shield is the caching so you don't execute complex checks multiple times.