introproventures / graphql-jpa-query

Generate GraphQL Query Api for your JPA Entity Models
https://github.com/introproventures/graphql-jpa-query
Apache License 2.0
195 stars 54 forks source link

Spring Security integration (authentication and user/role/permission/row/acl -based authorization) #221

Open Ernio3 opened 4 years ago

Ernio3 commented 4 years ago

I am pretty new to this project (which I take much greater pleasure in exploring compared to other's alike, just because it's code-first JPA) and actually whole GraphQL so mind my lack of detailed knowledge. Said that, additional point of view might be of help.

So I followed issues like #160 and #219 and can't help to wonder how to actually secure anything in any app using this lib. The issues presented include all of:

Now based on http://graphql.github.io/learn/authorization/ we should:

Delegate authorization logic to the business logic layer

We are then presented with GraphQL solution:

var postRepository = require('postRepository');
var postType = new GraphQLObjectType({
  name: ‘Post’,
  fields: {
    body: {
      type: GraphQLString,
      resolve: (post, args, context, { rootValue }) => {
        return postRepository.getBody(context.user, post);
      }
    }
  }
});

...that basically does exactly that. Delegate relational mappings to services representing other side of the relation and accept user-data as arguments. Notice that if We were to use any of Spring Security annotations, We don't even have the need to accept any user-data arguments - those are all accessible by Spring Security itself when business layer is called. All that data is accessible from SecurityContext and can be read from basically anywhere (be it request token or database when security is being checked).

So first since I can't find it anywhere in this project - is it capable of supporting relation-to-service-method delegation? Does is do it automatically? Why or why not?

Just this simple delegation (which simply based on JPA @Entitiy and their respective JpaRepositories could be fully auto-generated based on class/field/getter/setter names) would solve ALL security problems regarding data access by moving them to service (business) layer.

On the other hand - let's talk about schema introspection access - this also could be automatized based on the same exact principle - client requesting introspection could easily get dynamically-generated response based on his SecurityContext and respective Spring Security annotations. Then if that client would somehow know about schema anyway (not through introspection, but by e.g. a guess) it would also be easy to just omit those requested fields on server (not emit error [or emit common one with no-such-query] since that would prove that those fields exist).

The ONLY drawback I see is having to depend on Spring Security Core, but that also can be optional integration functionality, because why not?

All in all - how much of what I am saying is implemented (because maybe it is not documented) and why not take such approach?

igdianov commented 4 years ago

@Ernio3 Thank you for you comment. Security is an aspect specific to a particular application business domain and there are so many way to apply security to the subject. For Graphql domain there are 3 aspects:

Each aspect implementation depends on application that provides Graphql Api access to the data. There is a need to create a security framework to make it pluggable.

Feel free to create a PR with tests that address your use case, so we can collaborate on this topic.

molexx commented 4 years ago

Another one: if the client doesn't need it at runtime can the schema be not sent?