Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Spring Security (needs CSRF Token for graphiql) #4

Closed
benneq opened this issue Aug 20, 2018 · 11 comments
Closed

Support for Spring Security (needs CSRF Token for graphiql) #4

benneq opened this issue Aug 20, 2018 · 11 comments
Labels
enhancement New feature or request

Comments

@benneq
Copy link

benneq commented Aug 20, 2018

When adding spring-boot-starter-security you have to disable CSRF protection, because the graphiql user interface doesn't send csrf token when doing requests to POST /graphql.

Don't know if that's possible at all. Else just close this issue.

@BaldyLocks
Copy link
Member

We were gonna do proper spring security integration now that SPQR 0.9.8 is out. The idea is to first release 0.0.2 that would just support basic functionality that's present now. And after that move on to more advanced use cases.
I'll keep it open until we get to that point one way or the other.

@BaldyLocks BaldyLocks added the enhancement New feature or request label Aug 21, 2018
@hamidsafdari
Copy link

@BaldyLocks, I'm using graphql-spqr-spring-boot-starter and when I add spring security, I can login and access the graphiql page but I have to add /graphql url to the .permitAll() list. Even when I do that, the SecurityContextHolder returns an anonymousUser inside a GraphQLQuery. This happens only to graphql queries. When I do a simple REST request, the SecurityContextHolder gives me the logged in user and the granted authorities.

I know there is a way to enable spring security annotations with graphql-spqr but I guess it doesn't work with this (graphql-spqr-spring-boot-starter) library right now. I've looked here, here and here but I'm not quite sure how to make it work yet.

I'm guessing I will have to ditch the spring boot starter and use plain grqphql-spqr, add a controller and inside it, add all my types? Something like this. Right?

@BaldyLocks
Copy link
Member

Well you shouldn't have problems of that kind, the improvements we were going to do are regarding filtering the schema as well, the query execution should be working with method level security.
The way spring security works is that it uses a filter to populate the security context (authorization object) and store it as a thread local value, SecurityContextHolder just accesses that thread local, if you're using the same thread for the whole request you shouldn't be having a problem of this kind.
Could you maybe provide a minimal example somewhere ?

@hamidsafdari
Copy link

I made a minimum working example. I hope it's minimum enough. :)

You will only have to do gradle bootRun. I've made a graqhql query to return an auth object. I'm probably writing too much, but I'm hoping this could save you a couple of minutes. To test the query run:

curl 'http://localhost:8888/graphql' -H 'Content-Type: application/json' --data-binary '{"query":"{ auth { username }}","variables":null}'

Also, I've written a controller that binds to the URL http://localhost:8888/test and returns the word hello and logs the current principal and granted authorities to the console. You will have to log in with root and root. The console shows the current user with its role (which is ADMIN) when using the /test endpoint but when using the graphql query, an anonymousUser is returned even after login.

The /test URL has a @PreAuthorize("hasRole('ADMIN')") annotation. I enabled the same for the graphql query but I got that proxy error thing so I disabled it.

spqr-mwe.zip

@hamidsafdari
Copy link

@BaldyLocks, is there a workaround for this? Could I maybe check for every request and if they match one from a defined list, I ask for authentication?

@BaldyLocks
Copy link
Member

@hamidsafdari sorry for not answering for so long, life decided to get complicated lately. You could do that, however you shouldn't have to, let me first check your example this evening and see what's the problem.

@hamidsafdari
Copy link

hamidsafdari commented Oct 24, 2018

So, it looks like there was something wrong with my setup. I can't replicate my first problem. Now if I log in, I do get the correct user and authorities using graphql.

The second problem still stands though. If I annotate my graphql query with an annotation like @PreAuthorize("hasRole('ADMIN')") I get that error about dyanmic proxies. So the URL referred in that error says I should create a schema by myself but that's not what the spring boot starter is for, right?

I've also whipped up another (not so much) minimal example with a home page, a login and logout link. It also shows the name of the current user. Just saving the time running a cURL request in the console.

spqr-mwe-002.zip

@BaldyLocks
Copy link
Member

@hamidsafdari Yes we see the problem, spqr gets a dynamic proxy generated by Spring and doesn't know how to handle it. The immediate workaround would be to create a custom resolver builder that would use Spring utils to unwrap the proxy. We'll try to implement it over the weekend in the starter so you don't have to do it yourself.

@hamidsafdari
Copy link

That would be awesome. I'm working on this other project that has around 20 or so entity objects. Adding all the services to the resolver doesn't seem like a good way to go.

@kaqqao
Copy link
Member

kaqqao commented Nov 26, 2018

I've pushed a fix for #12 which, if I understand the conversation right, should close this issue as well.
I'll release version 0.0.3 with the fix later today.

@kaqqao
Copy link
Member

kaqqao commented Feb 24, 2019

#12 fixed the issue, so this can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants