Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • SensioLabs Professional services to help you with Symfony
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by
  1. Home
  2. Documentation
  3. Security
  4. The Entry Point: Helping Users Start Authentication

The Entry Point: Helping Users Start Authentication

Edit this page

When an unauthenticated user tries to access a protected page, Symfony gives them a suitable response to let them start authentication (e.g. redirect to a login form or show a 401 Unauthorized HTTP response for APIs).

However sometimes, one firewall has multiple ways to authenticate (e.g. both a form login and a social login). In these cases, it is required to configure the authentication entry point.

You can configure this using the entry_point setting:

1
2
3
4
5
6
7
8
9
10
11
12
13
# config/packages/security.yaml
security:

    # ...
    firewalls:
        main:
            # allow authentication using a form or a custom authenticator
            form_login: ~
            custom_authenticators:
                - App\Security\SocialConnectAuthenticator

            # configure the form authentication as the entry point for unauthenticated users
            entry_point: form_login
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- config/packages/security.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:srv="http://symfony.com/schema/dic/services"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        https://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/security
        https://symfony.com/schema/dic/security/security-1.0.xsd">

    <config>
        <!-- ... -->

        <!-- entry-point: configure the form authentication as the entry
                          point for unauthenticated users -->
        <firewall name="main"
            entry-point="form_login"
        >
            <!-- allow authentication using a form or a custom authenticator -->
            <form-login/>
            <custom-authenticator>App\Security\SocialConnectAuthenticator</custom-authenticator>
        </firewall>
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// config/packages/security.php
use App\Security\SocialConnectAuthenticator;
use Symfony\Config\SecurityConfig;

return static function (SecurityConfig $security): void {
    $security->enableAuthenticatorManager(true);
    // ....

    // allow authentication using a form or HTTP basic
    $mainFirewall = $security->firewall('main');
    $mainFirewall
        ->formLogin()
        ->customAuthenticators([SocialConnectAuthenticator::class])

        // configure the form authentication as the entry point for unauthenticated users
        ->entryPoint('form_login');
    ;
};

Note

You can also create your own authentication entry point by creating a class that implements AuthenticationEntryPointInterface. You can then set entry_point to the service id (e.g. entry_point: App\Security\CustomEntryPoint)

Multiple Authenticators with Separate Entry Points

However, there are use cases where you have authenticators that protect different parts of your application. For example, you have a login form that protects the main website and API end-points used by external parties protected by API keys.

As you can only configure one entry point per firewall, the solution is to split the configuration into two separate firewalls:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# config/packages/security.yaml
security:
    # ...
    firewalls:
        api:
            pattern: ^/api/
            custom_authenticators:
                - App\Security\ApiTokenAuthenticator
        main:
            lazy: true
            form_login: ~

    access_control:
        - { path: '^/login', roles: PUBLIC_ACCESS }
        - { path: '^/api', roles: ROLE_API_USER }
        - { path: '^/', roles: ROLE_USER }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- config/packages/security.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:srv="http://symfony.com/schema/dic/services"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        https://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/security
        https://symfony.com/schema/dic/security/security-1.0.xsd">

    <config>
        <!-- ... -->
        <firewall name="api" pattern="^/api/">
            <custom-authenticator>App\Security\ApiTokenAuthenticator</custom-authenticator>
        </firewall>

        <firewall name="main" anonymous="true" lazy="true">
            <form-login/>
        </firewall>

        <rule path="^/login" role="PUBLIC_ACCESS"/>
        <rule path="^/api" role="ROLE_API_USER"/>
        <rule path="^/" role="ROLE_USER"/>
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// config/packages/security.php
use App\Security\ApiTokenAuthenticator;
use App\Security\LoginFormAuthenticator;
use Symfony\Config\SecurityConfig;

return static function (SecurityConfig $security): void {
    $apiFirewall = $security->firewall('api');
    $apiFirewall
        ->pattern('^/api')
        ->customAuthenticators([ApiTokenAuthenticator::class])
    ;

    $mainFirewall = $security->firewall('main');
    $mainFirewall
        ->lazy(true)
        ->formLogin();

    $accessControl = $security->accessControl();
    $accessControl->path('^/login')->roles(['PUBLIC_ACCESS']);
    $accessControl->path('^/api')->roles(['ROLE_API_USER']);
    $accessControl->path('^/')->roles(['ROLE_USER']);
};
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version

    Symfony 7.1 is backed by

    Measure & Improve Symfony Code Performance

    Measure & Improve Symfony Code Performance

    Peruse our complete Symfony & PHP solutions catalog for your web development needs.

    Peruse our complete Symfony & PHP solutions catalog for your web development needs.

    Version:
    • Multiple Authenticators with Separate Entry Points

    Symfony footer

    Avatar of Wouter de Wild, a Symfony contributor

    Thanks Wouter de Wild for being a Symfony contributor

    1 commit • 15 lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • What is Symfony?
      • Symfony at a Glance
      • Symfony Components
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • Symfony Community
      • SymfonyConnect
      • Events & Meetups
      • Projects using Symfony
      • Contributors
      • Symfony Jobs
      • Backers
      • Code of Conduct
      • Downloads Stats
      • Support
    • Blog

      • All Blog Posts
      • A Week of Symfony
      • Case Studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Living on the edge
      • Releases
      • Security Advisories
      • Symfony Insight
      • Twig
      • SensioLabs Blog
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Powered by

    Follow Symfony