4

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?

Bird87 ZA
  • 2,313
  • 8
  • 36
  • 69

1 Answers1

4

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 ] }
  • Thanks for the response. Could you perhaps edit your answer and give an example how you would set up the providers in the firewall? I'm very new to Symfony 4 and this is the first project I'm attempting from scratch. – Bird87 ZA Apr 05 '19 at 20:14
  • After reading your answer again after taking a break from the code for a while, I figured out what you meant and saw the issue. Thanks a lot for the assistance. – Bird87 ZA Apr 07 '19 at 16:29
  • @Marcus, seems like you've created an unregistered account and a registered account. You can use this page to merge the accounts https://stackoverflow.com/contact. This way you can edit your own posts without them being in the queue. – Bhargav Rao Apr 07 '19 at 21:35