authenticationsymfony

Symfony losing auth session between login and redirect


I have an app that's has a form login which has been working fine.

I then added an api side to it using this guide. Now my log in on the web side doesn't work anymore.

This is my security.yaml file:

security:
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        users:
            entity:
                class: 'App\Entity\User'
                property: 'username'
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            pattern: ^/
            anonymous: true
            guard:
                authenticators:
                    - App\Security\LoginFormAuthenticator
            form_login:
                login_path: app_login
                check_path: app_login
            logout:
                path: app_logout
                target: app_user_index
        secured_area:
            form_login:
                csrf_token_generator: security.csrf.token_manager
    encoders:
        App\Entity\User:
            algorithm: bcrypt
            cost: 12

    role_hierarchy:
        ROLE_ADMIN: ROLE_USER

            # activate different ways to authenticate

            # http_basic: true
            # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate

            # form_login: true
            # https://symfony.com/doc/current/security/form_login_setup.html

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        # - { path: ^/delete, roles: ROLE_ADMIN }
        # - { path: ^/profile, roles: ROLE_USER }

I'm not sure what else I need to post, but I can't think of any other thing that might have changed that could cause it to break.

If I revert to a point before implementing the API, login works fine again.

What could be the issue?


Solution

  • Try comparing the file before and after to see the differences.

    Have you checked the logs? Are you getting an error?

    As the article talks about changing a number of different files, it's hard to tell. I.e. Your file posted does not contain any of the stuff in the article, like the ^/api firewall

    Maybe create the skeleton line for line in the article in a separate folder, then compare with your project, file by file, adding the skeleton stuff...

    It seems like you are not telling your main firewall which provider to use for authentication, so your api one could be overriding it...

    I.e. Your main: form_login: provider: needs to be users, and your api can use the fos_user bundle

    Both should be able to use the same provider for with as long as the field names are the same

    Edit: 1) Checkout symphony firewalls and access control

    2) Decide whether you want the same users as your main site, or a different user provider for the api

    3) Point the form_login in the relevant section of the firewall to the user provider you want to use

    Above you have one provider registered, "users" in the provider section. Assuming you wanted separate users to your main site: If you followed the article, you would have put "fos_userbundle" as another provider in that section, and added the firewall sections to allow oauth for the api. Under "form_login" on "aouth_authorize" there is a provider that points to the fos_userbundle. You should have also added the api route to control which route your api responds to (pattern: ^/api <== any route starting with api)

    I suspect your user provider under the main section now doesn't know which user bundle to use to authenticate. i.e. have you tried to login as an api user on your main site? Does it authenticate? If so, you need to tell your "main" section in the firewall, that the user provider must be the "users" provider by adding provider: users to the "form_login" section of the firewall.

    If you want to use a separate user provider for your main site and your api:

    (untested code)

    security:
        # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
        providers:
            users:
                entity:
                    class: 'App\Entity\User'
                    property: 'username'
            fos_userbundle:
                id: fos_user.user_provider.username
    
        firewalls:
            oauth_token:
                pattern:    ^/oauth/v2/token
                security:   false
            oauth_authorize:
                pattern:    ^/oauth/v2/auth
                form_login:
                    provider: fos_userbundle
                    check_path: /oauth/v2/auth_login_check
                    login_path: /oauth/v2/auth_login
                    use_referer: true
            api:
                pattern:    ^/api
                fos_oauth:  true
                stateless:  true
                anonymous:  false
    
            dev:
                pattern: ^/(_(profiler|wdt)|css|images|js)/
                security: false
            main:
                pattern: ^/
                anonymous: true
                guard:
                    authenticators:
                        - App\Security\LoginFormAuthenticator
                form_login:
                    provider: users
                    login_path: app_login
                    check_path: app_login
                logout:
                    path: app_logout
                    target: app_user_index
            secured_area:
                form_login:
                    csrf_token_generator: security.csrf.token_manager
    
        encoders:
            App\Entity\User:
                algorithm: bcrypt
                cost: 12
            FOS\UserBundle\Model\UserInterface: bcrypt
    
        role_hierarchy:
            ROLE_ADMIN: ROLE_USER
    
                # activate different ways to authenticate
    
                # http_basic: true
                # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
    
                # form_login: true
                # https://symfony.com/doc/current/security/form_login_setup.html
    
        # Easy way to control access for large sections of your site
        # Note: Only the *first* access control that matches will be used
        access_control:
            # - { path: ^/delete, roles: ROLE_ADMIN }
            # - { path: ^/profile, roles: ROLE_USER }
            - { path: ^/api, roles: [ IS_AUTHENTICATED_FULLY ] }
    

    If you want to use the same provider for the main site and the api:

    (untested code)

    security:
        # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
        providers:
            users:
                entity:
                    class: 'App\Entity\User'
                    property: 'username'
    
        firewalls:
            oauth_token:
                pattern:    ^/oauth/v2/token
                security:   false
            oauth_authorize:
                pattern:    ^/oauth/v2/auth
                form_login:
                    provider: users
                    check_path: /oauth/v2/auth_login_check
                    login_path: /oauth/v2/auth_login
                    use_referer: true
            api:
                pattern:    ^/api
                fos_oauth:  true
                stateless:  true
                anonymous:  false
    
            dev:
                pattern: ^/(_(profiler|wdt)|css|images|js)/
                security: false
            main:
                pattern: ^/
                anonymous: true
                guard:
                    authenticators:
                        - App\Security\LoginFormAuthenticator
                form_login:
                    provider: users
                    login_path: app_login
                    check_path: app_login
                logout:
                    path: app_logout
                    target: app_user_index
            secured_area:
                form_login:
                    csrf_token_generator: security.csrf.token_manager
    
        encoders:
            App\Entity\User:
                algorithm: bcrypt
                cost: 12
    
        role_hierarchy:
            ROLE_ADMIN: ROLE_USER
    
                # activate different ways to authenticate
    
                # http_basic: true
                # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
    
                # form_login: true
                # https://symfony.com/doc/current/security/form_login_setup.html
    
        # Easy way to control access for large sections of your site
        # Note: Only the *first* access control that matches will be used
        access_control:
            # - { path: ^/delete, roles: ROLE_ADMIN }
            # - { path: ^/profile, roles: ROLE_USER }
            - { path: ^/api, roles: [ IS_AUTHENTICATED_FULLY ] }