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

Service dependency injection for controller action: Getting CSP nonce in controller #345

Open
Adambean opened this issue May 18, 2024 · 6 comments

Comments

@Adambean
Copy link

Hello,

Does this bundle expose any services for use with a controller action via dependency injection? debug:autowiring didn't appear to reveal any.

The purpose for this is I need to provide a ReCAPTCHA bundle form instance with a nonce from this CSP provider.

@martijnc
Copy link
Contributor

You can use ContentSecurityPolicyListener::getNonce('script') to get a script nonce that will be included in the generated CSP header. You can find the listener in the container as nelmio_security.csp_listener.

@Adambean
Copy link
Author

Adambean commented Jun 1, 2024

Thanks for your reply @martijnc.

Is the "nelmio_security.csp_listener" service available to dependency injection? I don't see anything from "nelmio_security" available when searching for it with debug:autowiring --all, and it can't be invoked from the container via get(). (ContentSecurityPolicyListener::getNonce() can't be called statically.)

@martijnc
Copy link
Contributor

martijnc commented Jun 1, 2024

The nelmio_security.csp_listener service isn't marked public so get()-ing it from the container may not work because it's likely being inlined. But you should be able to inject it into your service with DI.

Can you find it with debug:container nelmio_security.csp_listener?

@Adambean
Copy link
Author

Adambean commented Jun 2, 2024

I see 26 services containing "nelmio_security" via debug:container, including "nelmio_security.csp_listener" as "Nelmio\SecurityBundle\EventListener\ContentSecurityPolicyListener". Unfortunately none of these are available for auto-wiring (not present in debug:autowiring), therefore they can't be used for DI.

I did attempt to declare "Nelmio\SecurityBundle\EventListener\ContentSecurityPolicyListener" in my services configuration to be available for auto-wiring however the service doesn't appear to be compatible with that:

Cannot autowire service "Nelmio\SecurityBundle\EventListener\ContentSecurityPolicyListener": argument "$report" of method "__construct()" references class "Nelmio\SecurityBundle\ContentSecurityPolicy\DirectiveSet" but no such service exists.

I think perhaps I've missed an approach to DI that predates auto-wiring? I went from the Symfony 2/3 days where using $this->get() or $this->container->get() up to Symfony 6/7 whereby auto-wiring was the thing to do. I'll read the service container documentation to see what I've missed.

@martijnc
Copy link
Contributor

martijnc commented Jun 2, 2024

Because autowiring for the service does not work, you need to wire it manually via the service configuration. See "Explicitly Configuring Services and Arguments "on the documentation page you linked. You don't need to redefine the ContentSecurityPolicyListener service, you need to reference the existing one by its ID.

If your service is App\Security\ServiceThatNeedsTheNonce with the listener as the first constructor argument, the configuration for it would look something like this:

services:
    App\Security\ServiceThatNeedsTheNonce:
        arguments:
            - '@nelmio_security.csp_listener'

@Adambean
Copy link
Author

Adambean commented Jun 2, 2024

That seemed to work. I had to also include the other arguments that I had previously given with auto-wiring, but the CSP listener now goes into my class as expected. Thanks for the workaround.

Is there a particular reason why the CSP listener class would not support auto-wiring, or is it a pending improvement?

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

No branches or pull requests

2 participants