Steps to reproduce:
1. Enable REST, HAL and Basic Auth modules.
2. Allow permission on GET method for Content on Authenticated users.
3. Create a user.
4. Create a node.
5. Run the following command replacing username and password: curl --request GET --user username:password --header 'Accept: application/hal+json' http://d8.local/node/1
Expected: The hal+json version of the node.
Actual: The following circular reference error raises because Comment service needs an authenticated user:
Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException: Circular reference detected for service "current_user", path: "router_listener -> router -> router.dynamic -> url_generator -> route_processor_manager -> route_processor_csrf -> csrf_token -> current_user -> comment.manager". in Symfony\Component\DependencyInjection\Container->get() (line 282 of /var/www/d8/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Container.php).
Comment | File | Size | Author |
---|---|---|---|
#42 | interdiff.txt | 662 bytes | dawehner |
#42 | comment-2182055-42.patch | 9.8 KB | dawehner |
#34 | comment-2182055-34.patch | 9.72 KB | dawehner |
Comments
Comment #1
juampynr CreditAttribution: juampynr commentedHere is a patch that demonstrates this issue. I simply enabled comment module to the Authentication test and verified that the REST request returns a JSON response.
Comment #2
dawehnerComment #3
dawehnerHere is some research we (webflo, dawehner) have done.
The problem is basically the following: The
csrf_token
service needs the current user, so the authentication starts.Normally (for all cases in tests) we either use the Cookie provider (which does not load the user). In this case csrf token can get the user
and the request continues.
In the case "basic authentication" usecase we authenticate the user and then load the new authenticated user. This will trigger hook_entity_load,
which will call comment_entity_load() which requires the comment.manager service. That one requires the current user and we have the circular dependency.
While debugging we realized a couple of points:
This is a potential sign that we should better split up the service. The word "manager" does not tell us anything about the actual work done by the class. If we split it up we would have solved the circular dependency
In general @damiankloip wanted to work on making the current user not get fetched automatically but '@current_user' should be just some kind of factory, so we authenticate later. This should also solve the problem described in this issue.
The patch does fixes the first and second point but certainly does not fix the actual root of the issue.
Comment #8
BerdirThat's similar to my suggestion to only have the authentication manager as a service that's passed around (We can still have Drupal::currentUser()), which would essentially be the same.
Comment #9
larowlanPatch looks OK, good catch on content entities, I did ask for a hook_content_entity_load somewhere, but forget to come back for this cleanup
Comment #10
ssemashka CreditAttribution: ssemashka commentedJust tried authencation.patch and went through listed steps and got the error:
Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: in Drupal\Core\EventSubscriber\AccessSubscriber->onKernelRequestAccessCheck() (line 87 of /home/s77aec018cc5a771/www/core/lib/Drupal/Core/EventSubscriber/AccessSubscriber.php)
Comment #11
ssemashka CreditAttribution: ssemashka commentedComment #12
linclark CreditAttribution: linclark commentedLet's add the comment module to the test as juampy did, if only temporarily, so that we can know when this is actually passing.
Comment #14
andypostTo fix that properly the
CommentManager::forbiddenMessage()
should be moved out manager, probably toCommentViewBuilder
From IRC:
<alexpott> andypost: I'd be tempted to split CommentManager into two - CommentManager that does the higher level stuff with users etc... and CommentFieldManager (or something like that) which does the low level entity management stuff.
Related #2180109: Change the current_user service to a proxy
comment_entity_load() should gone in #148849: Refactor {comment_entity_statistics} into performant Field
Wrong way!
Manager should not depends on current_user at all
Comment #15
blainelang CreditAttribution: blainelang commentedThis error occurs as well for a content type 'article' on a clean install without a comment field.
Comment #16
andypostComment manager should not depend on user.
So patch removes this dependency.
PS: there's issue for split #2188287: Split CommentManager in two
Comment #17
andypostNow with comment module dependency as #12 to test dependecies
Comment #20
andypostDebugged this, actual problem caused by
url_generator
dependency!Current user calls
user_authenticate()
that callsuser_load_by_name()
that invokes entity system too early, so other services is trying to initialize... the comment manager needs url_generator to up but container detects that this service in progress of creation... and fails.Comment #21
andypostdiscussed in IRC with @dawehner, my point is - no code (csrf is not a exceptional) should be executed before auth,
So #2180109: Change the current_user service to a proxy can't help with the issue
Comment #22
damiankloip CreditAttribution: damiankloip commentedYes, it could have done if we went with one of the earlier patches. But people seem to be against that. That issue already mentions that point, so maybe have a look.
Comment #23
juampynr CreditAttribution: juampynr commentedRe-rolling #16
Comment #24
juampynr CreditAttribution: juampynr commentedAs mentioned by @andypost, the patch fixes the issue at the comment service level, but it still exists at the url_generator service.
I just repeated the steps listed at the top and got the following error:
Comment #25
damiankloip CreditAttribution: damiankloip commentedI think this works now #2180109: Change the current_user service to a proxy is in?
Comment #26
dawehnerThis worked for me.
Comment #27
andypostOnce you remove variable then you need to remove it from constructor and service definition as well
Comment #28
andypostComment #29
dawehnerActually it is the other way round.
Comment #30
andypostthen no reason to check the same in manager
Then remove $container aswell
Comment #31
dawehnerI kinda dislike to do access checking in the manager ...
Maybe at the same time we could already inject the module handler.
Comment #32
dawehnerFixed the points of andrey
Comment #33
andypostThat's why I remove current_user from dependencies of manager in #16, this one is only needed here
Comment #34
dawehnerAaaaaaah, here is a patch. Thank you for the pointer.
Comment #35
juampynr CreditAttribution: juampynr commentedComment #36
juampynr CreditAttribution: juampynr commentedI repeated the steps listed at the issue description without the above patch and could not reproduce the issue anymore. I will test it further to see if I see if I can reproduce it again.
Comment #37
dawehner@juampy
The reason might be probably because we have the account proxy now.
Comment #38
andypostPart of patch included in #2188287: Split CommentManager in two
Comment #39
dawehner34: comment-2182055-34.patch queued for re-testing.
Comment #40
andypostAll this changes are needed and critically
The primary purpose of the patch
Comment #41
catchIt's not clear from the issue summary, nor a quick scan through the comments. What else is getting passed in here? At least needs an inline comment.
Comment #42
dawehnerDoes that clarify it?
Comment #43
andypostagreed, exactly
Comment #45
catchOh doh it's a generic entity hook so it runs on everything. I'd forgotten we're still loading comment statistics onto entity objects. We should just rip that out, but not here.
Committed/pushed to 8.x, thanks!