如何仅在完全身份验证后强制经过身份验证的用户在Symfony2中使用HTTPS?

时间:2014-07-31 06:02:08

标签: symfony symfony-2.2

我需要在Symfony 2.2中使用https,但前提是用户已完全通过身份验证。

2 个答案:

答案 0 :(得分:1)

使用onKernalRequest事件监听器获得解决方案。

我的onKernelRequest事件服务:

<?php

namespace Acme\DemoBundle\Listener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\HttpKernelInterface;

/**
 * force https for fully authenticated user
 */
class ForceHttpsListner
{

    /**
     * container
     * 
     * @var type 
     */
    private $container;

    /**
     * 
     * @param type $container
     */
    public function __construct($container)
    {
        $this->container = $container;
    }

    /**
     * on kernel request
     * 
     * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
     */
    public function onKernelRequest(GetResponseEvent $event)
    {

        //all urls which always use https, specefied using requires_channel in security.yml
        $httpsPaths= [
            '/login',
            '/resetting/request',
            '/register/',
        ];

        if ($event->getRequestType() === HttpKernelInterface::MASTER_REQUEST ) {

            $request = $event->getRequest();

            if ($this->container->get('security.context')->getToken()
                    && $this->container->get('security.context')
                            ->isGranted('IS_AUTHENTICATED_FULLY')) {

                if (!$request->isSecure()) {

                    $request->server->set('HTTPS', true);
                    $request->server->set('SERVER_PORT', 443);
                    $event->setResponse(new RedirectResponse($request->getUri()));

                }

            } else {

                //echo $request->getPathInfo(); exit;                
                if ($request->isSecure() 
                        && !in_array($request->getPathInfo(), $httpsPaths)) {

                    $request->server->set('HTTPS', false);
                    $request->server->set('SERVER_PORT', 80);
                    $event->setResponse(new RedirectResponse($request->getUri()));
                }

            }

        }

    }
}

注册服务

services:
    kernel.listener.forcehttps:
        class: Acme\DemoBundle\Listener\ForceHttpsListner
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
        arguments: [ @service_container ]

security.yml中的access_control

security:
    access_control:
        - { path: ^/_wdt, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/_profiler, role: IS_AUTHENTICATED_ANONYMOUSLY }        
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

        # Secured part of the site
        # This config requires being logged for the whole site and having the admin role for the admin part.
        # Change these rules to adapt them to your needs
        - { path: ^/admin, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN, ROLE_SUPER_EDITOR] }
        - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }

答案 1 :(得分:0)

您需要创建一个RequestEventListener,在路由和安全性之后触发,以便在其中处理

1)安全上下文(查看用户是否完全通过身份验证)
2)路由器组件中的实际请求路由(并将其与配置数组匹配)

然后决定是否强制重定向到https,如果不是这样的话。