xfscrypt
xfscrypt

Reputation: 286

Redirect loop on any url with https in Symfony2

Wherever I try to implement the https channel, there will be an infinite redirect loop. This is what the security.yml file looks like:

security:
    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        main:
            pattern: .*
            form_login:
                provider: fos_userbundle
                csrf_provider: form.csrf_provider
                check_path: /login_check
                login_path: /login
                default_target_path:  /home
            logout:
                path:   /logout
                target: /index
            security: true
            anonymous: true
            remember_me:
                key:      mySecret
                lifetime: 604800 #seven days
                path:     /
                domain:   ~

    access_control:
        - { path: ^/js, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/css, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/_wdt, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/_profiler, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/index*, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/.*, role: ROLE_ADMIN }
        - { path: ^/.*, roles: ROLE_USER }

For example if I change the admin path to:

- { path: ^/admin/.*, role: ROLE_ADMIN, requires_channel: https }

the loop will occur. Also in the routing/entity.yml I tried something like this:

entity_index:
  pattern: /
  defaults: { _controller: MyBundle:Entity:index }
  schemes: [https]

Anybody has an idea how to solve this?

Upvotes: 3

Views: 2238

Answers (3)

Michael Czolko
Michael Czolko

Reputation: 2858

For me the problem was not on the side of Symfony but Nginx config was wrong. In case you're using Nginx as well make sure, that you don't have this set: fastcgi_param HTTPS off; Otherwise set it to on and restart the server. Hope it helps

Upvotes: 1

AlexK
AlexK

Reputation: 469

I had the same problem because the server was sitting behind a reverse proxy, which commmunicated over ssl with the client, but http with the server the application was running on. I only used this, because the connection between RP and App Server is secure since it doesn't leave the internal network. if you're really positive you really have SSL running and this problem occurs, there's one ugly fix for that... But it's really last resort and to use on your own risk:

you can overwrite the server vars in your app.php like this:

$_SERVER['HTTPS'] = 'on'; 
$_SERVER['SERVER_PORT'] = 443;

again, this is an ugly fix, not a solution, only use at your only risks and responsibilty, I wouldn't do this if I didn't have the problem with my reverse proxy not forwarding the port and wasn't 100% sure I had SSL between client and RP. Don't forget, this makes you vulnerable if you're not really running valid ssl

Upvotes: 2

whiplashomega
whiplashomega

Reputation: 49

While it looks like the original poster's issue was a case of HTTPS not being enabled on their development server, I recently encountered a similar issue, and thought I would share how I resolved it.

In my case, my security.yml looked something like this:

security:
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_provider: form.csrf_provider
                default_target_path: /dm
            logout: true
            anonymous:    true

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/dm, role: IS_AUTHENTICATED_REMEMBERED, requires_channel: https }
        - { path: ^/dm/*, role: IS_AUTHENTICATED_REMEMBERED, requires_channel: https }
        - { path: ^/*, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

And in my case, https worked on every page, except any that required any sort of login. Additionally, my javascript and css files I was pulling from google cdn were failing to load. In the end there were two issues with the code that I had:

Issue 1:

Identifying the channel multiple times. In my case, I had a directive in my routing.yml file that was specifying to use http, as well as the one in my security.yml file above, specifying https. This meant that the paths managed by my app (the ones that required me to login) were being routed to https by the security system, which sent it back to the routing system that tried to change it to http, then sent it back to the security system which changed it back to https, infinite redirect loop. By removing the directive in routing.yml, this issue was fixed.

Issue 2:

I was missing one line from my cdn configuration for assetic:

ssl: ['https://ajax.googleapis.com/ajax/libs/']

Placed in config.yml like so:

framework:
    #esi:             ~
    translator:      { fallbacks: ["en"] }
    secret:          "%secret%"
    router:
        resource: "%kernel.root_dir%/config/routing.yml"
        strict_requirements: ~
    form:            ~
    csrf_protection: ~
    validation:      { enable_annotations: true }
    templating:
        engines: ['twig']
        #assets_version: SomeVersionScheme
        packages:
            cdn:
                base_urls:
                    http: ['https://ajax.googleapis.com/ajax/libs/']
                    ssl: ['https://ajax.googleapis.com/ajax/libs/']

Missing this line meant that assetic ignored my package definition when using ssl, and tried to load the files from my own server, where they didn't exist.

Upvotes: 0

Related Questions