보안


Symfony의 보안 시스템은 매우 강력하지만 설정할 때 혼란스러울 수도 있습니다. 이 큰 장에서는 방화벽(방화벽) 구성 및 사용자 로드부터 액세스 거부 및 사용자 개체 획득에 이르기까지 애플리케이션의 보안을 단계별로 설정하는 방법을 배웁니다. 필요에 따라 초기 설정을 수행하는 것이 어려울 수도 있습니다. 그러나 일단 완성되면 Symfony의 보안 시스템은 유연하고 (희망적으로) 사용하기 재미있습니다.

할 말이 많기 때문에 이 장은 여러 주요 장으로 구성됩니다.

  1. security.yml 설정 초기화(security.yml 的设置 (authentication/验证 );

  2. 拒绝访问你的程序 (authorization/授权 );

  3. 获取当前的User对象;

它们被细分为许多小块内容(但仍然令人着迷),像是 logging out加密用户密码

1)初始化security.yml的设置 (Authentication/验证) 

security系统在 app/config/security.yml 中进行配置。默认的配置是这样的:

PHP:// app/config/security.php$container->loadFromExtension('security', array(
    'providers' => array(
        'in_memory' => array(
            'memory' => null,
        ),
    ),
    'firewalls' => array(
        'dev' => array(
            'pattern'    => '^/(_(profiler|wdt)|css|images|js)/',
            'security'   => false,
        ),
        'default' => array(
            'anonymous'  => null,
        ),
    ),));
XML:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>
        <provider name="in_memory">
            <memory />
        </provider>         <firewall name="dev"            pattern="^/(_(profiler|wdt)|css|images|js)/"            security="false" />         <firewall name="default">
            <anonymous />
        </firewall>
    </config></srv:container>
YAML:# app/config/security.ymlsecurity:
    providers:
        in_memory:
            memory: ~
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        default:
            anonymous: ~

firewalls 键是security配置的 核心dev 防火墙并不重要,它只是确保Symfony开发工具 - 也就是居于 /_profiler/_wdt 之下的那些URL将不会被你的security所阻止。

你也可以针对请求中的其他细节来匹配一个请求(如 host主机)。阅读 如何把防火墙限制在特定请求 以了解更多内容和例程。

所有其他的URL将被 default 防火墙中处理(没有 pattern 键意味着它可以匹配所有 URL)。你可以认为防火墙就是你的security系统,因此通常只有一个主力防火墙就变得有意义了。但这并 意味着每一个URL都需要验证 - anonymous 键可以搞定这个。事实上,如果你现在去首页,是可以访问的,并将看到你以 anon.인증/확인

)

11.png

프로그램에 대한 액세스 거부(

authorization/authorization

)

현재 사용자 개체 가져오기 이 항목은 여러 개의 작은 조각으로 나누어져 있습니다(그러나 여전히 혼란스럽습니다). 사람들은 매료되었습니다) 로그아웃사용자 비밀번호 암호화 등이 있습니다.

1) security.yml 설정 초기화(인증/검증)

앱의 보안 시스템 구성 /config/security.yml에 있습니다. 기본 구성은 다음과 같습니다. 🎜
PHP:// app/config/security.php$container->loadFromExtension('security', array(
    // ...
    'firewalls' => array(
        // ...
        'default' => array(
            'anonymous'  => null,
            'http_basic' => null,
        ),
    ),));
XML:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>
        <!-- ... -->         <firewall name="default">
            <anonymous />
            <http-basic />
        </firewall>
    </config></srv:container>
YAML:# app/config/security.ymlsecurity:    # ...
    firewalls:        # ...
        default:
            anonymous: ~
            http_basic: ~
🎜방화벽 키는 보안 구성 🎜core🎜입니다. dev 방화벽은 중요하지 않습니다. 단지 Symfony 개발 도구, 즉 /_profiler/_wdt 아래의 URL이 작동하지 않도록 보장할 뿐입니다. 보안으로 인해 차단되었습니다. 🎜🎜🎜🎜요청의 다른 세부정보(예: 호스트)와 요청을 일치시킬 수도 있습니다. 자세한 내용과 예를 보려면
방화벽을 특정 요청으로 제한하는 방법🎜을 읽어보세요. 🎜🎜🎜🎜다른 모든 URL은 기본 방화벽에 의해 처리됩니다(pattern 키가 없으면 🎜모든 🎜 URL과 일치할 수 있음을 의미). 방화벽을 보안 시스템으로 생각할 수 있으므로 일반적으로 기본 방화벽을 하나만 사용하는 것이 합리적입니다. 하지만 이것이 🎜🎜 모든 URL을 확인해야 한다는 의미는 아닙니다. 익명 키가 이를 처리합니다. 실제로 지금 홈페이지에 접속하시면 anon.으로 "인증"이 되어 있는 것을 보실 수 있습니다. 인증됨 옆의 "예"에 속지 마십시오. 귀하는 여전히 익명의 사용자일 뿐입니다. 🎜🎜🎜🎜🎜 나중에 특정 URL이나 컨트롤러에 대한 액세스를 거부하는 방법(그 안에 포함된 작업)을 배우게 됩니다. 🎜🎜🎜🎜보안은 🎜매우🎜 구성 가능하며 모든 구성 옵션은 몇 가지 추가 지침과 함께 🎜보안 구성 참조🎜에 표시됩니다. 🎜🎜🎜

A) "사용자 인증 허용 방법" 구성

방화벽의 주요 작업은 사용자 인증을 허용하는 방법 을 구성하는 것입니다. 로그인 양식이 필요합니까? 아니면 HTTP 기본 인증인가요? 아니면 API 토큰인가요? 아니면 위의 모든 것입니까?

HTTP 기본 인증(이전 팝업)부터 시작하겠습니다. 이 기능을 활성화하려면 방화벽에 http_basic을 추가하세요. http_basic 到firewall下面:

// src/AppBundle/Controller/DefaultController.php
// ... use 
Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Symfony\Component\HttpFoundation\Response; class DefaultController extends Controller{
   /**
     * @Route("/admin")
     */
    public function adminAction()
    {
        return new Response('<html><body>Admin page!</body></html>');
    }}
PHP:// app/config/security.php$container->loadFromExtension('security', array(
    // ...
    'firewalls' => array(
        // ...
        'default' => array(
            // ...
        ),
    ),
   'access_control' => array(
       // require ROLE_ADMIN for /admin*
        array('path' => '^/admin', 'role' => 'ROLE_ADMIN'),
    ),));
XML:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>
        <!-- ... -->         <firewall name="default">
            <!-- ... -->
        </firewall>         <!-- require ROLE_ADMIN for /admin* -->
        <rule path="^/admin" role="ROLE_ADMIN" />
    </config></srv:container>
真简单!要测试效果,你需要让用户登录并看到页面。为了让事情变的有趣,在 /admin 下创建一个新页面 。例如,如果你使用annotations,创建下例代码:
YAML:# app/config/security.ymlsecurity:    # ...
    firewalls:        # ...
        default:            # ...
    access_control:        # require ROLE_ADMIN for /admin*
        - { path: ^/admin, roles: ROLE_ADMIN }

接下来,在 security.yml 中添加一个 access_control 入口,以令用户必先登录方可访问URL:

PHP:// app/config/security.php$container->loadFromExtension('security', array(
    'providers' => array(
        'in_memory' => array(
            'memory' => array(
                'users' => array(
                    'ryan' => array(
                        'password' => 'ryanpass',
                        'roles' => 'ROLE_USER',
                    ),
                    'admin' => array(
                        'password' => 'kitten',
                        'roles' => 'ROLE_ADMIN',
                    ),
                ),
            ),
        ),
    ),
    // ...));
XML:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>
        <provider name="in_memory">
            <memory>
                <user name="ryan" password="ryanpass" roles="ROLE_USER" />
                <user name="admin" password="kitten" roles="ROLE_ADMIN" />
            </memory>
        </provider>
        <!-- ... -->
    </config></srv:container>
YAML:# app/config/security.ymlsecurity:
    providers:
        in_memory:
            memory:
                users:
                    ryan:
                        password: ryanpass
                        roles: 'ROLE_USER'
                    admin:
                        password: kitten
                        roles: 'ROLE_ADMIN'    # ...

你将学到关于 ROLE_ADMIN 以及后面的 2) 拒绝访问, Roles和其他授权 小节中的“拒绝访问”等更多内容。

太好了,如果你去访问 /admin

PHP:// app/config/security.php$container->loadFromExtension('security', array(
    // ...     'encoders' => array(
        'Symfony\Component\Security\Core\User\User' => 'plaintext',
    ),
    // ...));
XML:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>
        <!-- ... -->         <encoder class="Symfony\Component\Security\Core\User\User"            algorithm="plaintext" />
        <!-- ... -->
    </config></srv:container>
YAML:app/config/security.ymlsecurity:    # ...
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext    # ...
정말 쉽습니다! 효과를 테스트하려면 사용자가 로그인하여 페이지를 보도록 해야 합니다. 흥미롭게 만들려면 /admin 아래에 새 페이지를 만드세요. 예를 들어, 주석을 사용하는 경우 다음 코드를 생성하세요.

PHP:// app/config/security.php$container->loadFromExtension('security', array(
    // ...     'encoders' => array(
        'Symfony\Component\Security\Core\User\User' => array(
            'algorithm' => 'bcrypt',
            'cost' => 12,
        )
    ),
    // ...));

다음으로, 사용자가 로그인해야 하도록 security.ymlaccess_control 항목을 추가하세요. 먼저 URL에 액세스하세요:
222.png

XML:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>        <!-- ... -->         <encoder class="Symfony\Component\Security\Core\User\User"            algorithm="bcrypt"            cost="12" />         <!-- ... -->    </config></srv:container>
YAML:# app/config/security.ymlsecurity:    # ...
    encoders:
        Symfony\Component\Security\Core\User\User:
            algorithm: bcrypt
            cost: 12
1

ROLE_ADMIN에 대해 알아보세요. 2) 액세스 거부, 역할 및 기타 승인
"액세스 거부" 등 섹션에서 자세히 알아보세요.

좋습니다. /admin에 접속하시면 HTTP 기본 인증 팝업 로그인이 뜹니다.

그런데 어떤 아이디로 로그인하시나요? 사용자(정보)는 어디에서 오는가?
전통적인 형태를 사용하고 싶으신가요? 매우 좋은!

기존 로그인 양식 작성 방법을 참조하세요. 지원되는 다른 (인증) 방법은 무엇입니까? 구성 참조

를 참조하거나
직접 구축
하세요. 🎜🎜🎜🎜🎜🎜프로그램이 Google, Facebook 또는 Twitter와 같은 타사 서비스를 통해 로그인을 완료하는 경우 🎜HWIOAuthBundle🎜 커뮤니티 번들을 참조하세요. 🎜🎜🎜

B) "사용자 로드 방법" 구성

사용자 이름을 입력하면 Symfony가 어딘가에서 사용자 정보를 로드합니다. 이는 소위 "사용자 공급자"이며 이를 구성하는 것은 귀하의 책임입니다. Symfony에는 데이터베이스에서 사용자를 로드하는 방법이 내장되어 있지만 자신만의 사용자 공급자를 생성하는 것도 가능합니다.

가장 간단한 방법(그러나 많은 제한이 있음)은 security.yml 파일에서 프로그래밍된 사용자를 직접 로드하도록 Symfony를 구성하는 것입니다. 이를 "메모리 내" 공급자라고 하지만 "구성 내" 공급자로 생각하는 것이 더 좋습니다 security.yml 文件里直接加载写死在其中的用户。这被称为“in memory” provider,但把它观想为“in configuration” provider更合适些

$  php bin/console security:encode-password
PHP:// app/config/security.php$container->loadFromExtension('security', array(
    // ...     'providers' => array(
        'in_memory' => array(
            'memory' => array(
                'users' => array(
                    'ryan' => array(
                        'password' => 'a$LCY0MefVIEc3TYPHV9SNnuzOfyr2p/AXIGoQJEDs4am4JwhNz/jli',
                        'roles' => 'ROLE_USER',
                    ),
                    'admin' => array(
                        'password' => 'a$cyTWeE9kpq1PjqKFiWUZFuCRPwVyAZwm4XzMZ1qPUFl7/flCM3V0G',
                        'roles' => 'ROLE_ADMIN',
                    ),
                ),
            ),
        ),
    ),
    // ...));
XML:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>
        <!-- ... -->         <provider name="in_memory">
            <memory>
                <user name="ryan" password="a$LCY0MefVIEc3TYPHV9SNnuzOfyr2p/AXIGoQJEDs4am4JwhNz/jli" roles="ROLE_USER" />
                <user name="admin" password="a$cyTWeE9kpq1PjqKFiWUZFuCRPwVyAZwm4XzMZ1qPUFl7/flCM3V0G" roles="ROLE_ADMIN" />
            </memory>
        </provider>
    </config></srv:container>

类似 firewalls,你可以拥有多个 providers ,但你几乎只需要一个。如果你确实 拥有多个,你可以在防火墙的 provider 键(如 provider:in_memory

YAML:# app/config/security.ymlsecurity:    # ...
    providers:
        in_memory:
            memory:
                users:
                    ryan:
                        password: a$LCY0MefVIEc3TYPHV9SNnuzOfyr2p/AXIGoQJEDs4am4JwhNz/jli
                        roles: 'ROLE_USER'
                    admin:
                        password: a$cyTWeE9kpq1PjqKFiWUZFuCRPwVyAZwm4XzMZ1qPUFl7/flCM3V0G
                        roles: 'ROLE_ADMIN'
PHP:// app/config/security.php$container->loadFromExtension('security', array(
    // ...     'firewalls' => array(
        // ...
        'default' => array(
            // ...
        ),
    ),
   'access_control' => array(
       // require ROLE_ADMIN for /admin*
        array('path' => '^/admin', 'role' => 'ROLE_ADMIN'),
    ),));
XML:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>
        <!-- ... -->         <firewall name="default">
            <!-- ... -->
        </firewall>         <!-- require ROLE_ADMIN for /admin* -->
        <rule path="^/admin" role="ROLE_ADMIN" />
    </config></srv:container>
방화벽과 마찬가지로 여러 공급자를 가질 수 있습니다. , 하지만 거의 하나만 필요합니다. 둘 이상의 공급자가 do

있는 경우 방화벽의 provider 키(예: provider:in_memory)에서 "어떤
하나
사용할" 공급자를 구성할 수 있습니다.

참조
여러 공급자 설정에 대한 자세한 내용은 여러 사용자 공급자를 사용하는 방법
을 참조하세요. 🎜🎜🎜

사용자 이름은 admin, 비밀번호는 kitten으로 로그인해 보세요. 오류가 표시됩니다! admin 和密码 kitten 来登录。你应该看到一个错误!

No encoder has been configured for account "SymfonyComponentSecurityCoreUserUser"

要修复此问题 ,添加一个 encoders 健:

YAML:# app/config/security.ymlsecurity:    # ...
    firewalls:        # ...
        default:            # ...
    access_control:        # require ROLE_ADMIN for /admin*
        - { path: ^/admin, roles: ROLE_ADMIN }
PHP:// app/config/security.php$container->loadFromExtension('security', array(
    // ...     'access_control' => array(
        array('path' => '^/admin/users', 'role' => 'ROLE_SUPER_ADMIN'),
        array('path' => '^/admin', 'role' => 'ROLE_ADMIN'),
    ),));
XML:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>
        <!-- ... -->         <rule path="^/admin/users" role="ROLE_SUPER_ADMIN" />
        <rule path="^/admin" role="ROLE_ADMIN" />
    </config></srv:container>

User providers加载用户信息,并将其置于一个 User 对象中。如果你从数据库中加载用户 或者 从其他来源加载,你需要使用自定义的User类。但当你使用“in memory” provider时,它直接给了你一个 SymfonyComponentSecurityCoreUserUser 对象。

无论你使用什么样的User类,你都需要去告诉Symfony它们的密码加密算法是什么。在本例中,密码只是明文的文本,但很快,你要把它改成 bcrypt

如果你现在刷新,你就会登录进来!web除错工具栏会告诉你,你是何人,你的roles(角色)是什么:

4444t.png

由于此URL需要的是 ROLE_ADMIN ,如果你登录的是 ryan 用户,将被拒绝访问。更多内容参考后面的 [URL受到保护的条件(access_control](#catalog9)。

从数据库加载用户 

如果你想通过Doctrine Orm加载用户,很容易!参考 如何从数据库中(Entity Provider)加载Security系统之用户 以了解全部细节。

C) 对用户密码进行加密 

不管用户是存储在 security.yml 里,数据库里还是其他地方,你都需要去加密其密码。堪用的最好算法是 bcrypt

"SymfonyComponentSecurityCoreUserUser" 계정에 인코더가 구성되지 않았습니다


이 문제를 해결하려면 인코더 키를 추가하세요. # 🎜🎜#
YAML:# app/config/security.ymlsecurity:    # ...
    access_control:
        - { path: ^/admin/users, roles: ROLE_SUPER_ADMIN }
        - { path: ^/admin, roles: ROLE_ADMIN }
// ... public function helloAction($name){
    // The second parameter is used to specify on what object the role is tested.
    // 第二个参数用于指定“要将role作用到什么对象之上”
    $this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!');     // Old way / 老办法:
    // if (false === $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) {
    //     throw $this->createAccessDeniedException('Unable to access this page!');
    // }     // ...}
// ...use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; /**
 * @Security("has_role('ROLE_ADMIN')")
 */public function helloAction($name){
    // ...}

User 공급자는 사용자 정보를 로드하여 User 개체에 배치합니다. 데이터베이스에서 사용자를 로드하거나 다른 소스에서 로드하는 경우 , 사용자 정의 사용자 클래스를 사용해야 합니다. 하지만 "메모리 내" 공급자를 사용하면 SymfonyComponentSecurityCoreUser 개체가 직접 제공됩니다.


어떤 사용자 클래스를 사용하든 Symfony에게 비밀번호 암호화 알고리즘이 무엇인지 알려주어야 합니다. 이 경우 비밀번호는 일반 텍스트이지만 곧 bcrypt로 변경하고 싶을 것입니다.

지금 새로고침하시면 로그인됩니다! 웹 디버깅 도구 모음은 귀하가 누구인지, 귀하의 역할이 무엇인지 알려줍니다:

4444t.png
이 URL에는 ROLE_ADMIN이 필요하므로 로그인한 사용자는 입니다. 라이언 액세스가 거부됩니다. 자세한 내용은 다음 [URL 보호 조건(access_control)](#catalog9)을 참조하세요.

데이터베이스에서 사용자 로드

Doctrine Orm을 통해 사용자를 로드하려면 쉽습니다! 방법을 참조하세요. 데이터베이스에서 사용자 로드(엔티티 공급자)보안 시스템 사용자 로드를 통해 모든 세부 정보 확인 # 🎜🎜# 물론 이제 사용자 비밀번호는 지정된 알고리즘으로 암호화되어야 합니다. config.yml에 하드코딩된 사용자의 경우 내장 명령

C) 사용자 비밀번호 암호화 ¶< /a>

PHP:<?php if ($view['security']->isGranted('ROLE_ADMIN')): ?>
    <a href="...">Delete</a><?php endif ?>
Twig:{% if is_granted('ROLE_ADMIN') %}
    <a href="...">Delete</a>{% endif %}
    if (!$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
        throw $this->createAccessDeniedException();
    }     // ...}
#🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜을 사용하여 수행할 수 있습니다. ## 🎜🎜#
PHP:<?php if ($view['security']->isGranted(new Expression(
    '"ROLE_ADMIN" in roles or (user and user.isSuperAdmin())'))): ?>
    <a href="...">Delete</a><?php endif; ?>
#🎜🎜##🎜🎜##🎜🎜##🎜🎜#
Twig:{% if is_granted(expression(
    '"ROLE_ADMIN" in roles or (user and user.isSuperAdmin())')) %}
    <a href="...">Delete</a>{% endif %}
#🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#

다음과 같은 내용이 표시됩니다(비밀번호는 암호화되어 있음).

public function indexAction(){
    if (!$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
        throw $this->createAccessDeniedException();
    }     $user = $this->getUser();     // the above is a shortcut for this / 上面的写法是通过以下取法(再进行授权)的快捷方式
    $user = $this->get('security.token_storage')->getToken()->getUser();}
use Symfony\Component\HttpFoundation\Response;
// ... public function indexAction(){
  // ...     return new Response('Well hi there '.$user->getFirstName());}
public function indexAction(UserInterface $user = null){
    // $user is null when not logged-in or anon.
    // 当用户没有登陆,或者是anno.时,$user是null}

이제 모든 것이 동일합니다. 이전처럼. 그러나 데이터베이스에 저장되기 전에 비밀번호가 암호화되는 동적 사용자(예: 데이터베이스)가 있는 경우 이를 프로그래밍 방식으로 어떻게 암호화할 수 있습니까? 걱정하지 마세요. 자세한 내용은 수동 암호화 비밀번호를 참조하세요.

이 암호화 알고리즘이 지원되는지 여부는 PHP 버전에 따라 다르지만 여기에는 hash_algos이 포함됩니다. PHP 함수에서 반환된 알고리즘 및 일부 다른 것(예: bcrypt)도 지원됩니다. 예를 보려면 Security Referencebcrypt)都受到支持。参考 Security参考 中的 encoders인코더 옵션 키를 참조하세요.

사용자마다 다른 알고리즘을 사용하는 것도 가능합니다. 자세한 내용은 비밀번호 암호화 알고리즘을 동적으로 선택하는 방법을 참조하세요.

D) 구성 완료!

축하합니다! 이제 HTTP 기본 인증을 기반으로 작동하고 security.yml 파일에서 사용자를 로드하는 "인증 시스템"이 작동합니다. security.yml 文件中加载用户的“验证系统”了。

根据你的设置,尚有后续步骤:

2) 拒绝访问,Roles和其他授权方式 

现在,用户可以通过 http_basic 或者其他方式来登录你的程序。了不起呀!现在你需要学习如何拒绝访问(deny access)并且能与User对象一起工作。这被称为authorization(授权),它的工作是决定用户是否可以访问某些资源(如一个URL、一个model对象、一个被调用的方法等...)。

授权过程分为两个不同的方面:

  1. 用户在登录时收到一组特定的Roles(角色。如 ROLE_ADMIN)。

  2. 你添加代码,以便某个资源(例如url、控制器)需要一个特定“属性”(多数时候就是一个类似 ROLE_ADMIN 的role)才能被访问到。

  • 🎜는 기타 소스 🎜; 🎜
  • 🎜 " >승인🎜 섹션에서 액세스 거부, 사용자 개체 로드 및 역할 작동 방법을 알아보세요. 🎜
  • 2) 액세스 거부, 역할 및 기타 승인 방법 ¶🎜

    🎜이제 사용자는 http_basic 또는 다른 방법을 통해 프로그램에 로그인할 수 있습니다. 놀라운! 이제 액세스를 거부하고 사용자 개체를 사용하여 작업하는 방법을 배워야 합니다. 이를 승인(승인)이라고 하며 해당 작업은 사용자가 특정 리소스(예: URL, 모델 개체, 호출된 메서드 등)에 액세스할 수 있는지 여부를 결정하는 것입니다. 🎜🎜인증 프로세스는 두 가지 측면으로 나뉩니다. 🎜
    1. 🎜사용자는 로그인할 때 특정 역할 세트(역할. 예: ROLE_ADMIN)를 받습니다. 🎜
    2. 🎜리소스(예: URL, 컨트롤러)에 액세스하기 전에 특정 "속성"(주로 ROLE_ADMIN과 같은 역할)이 필요하도록 코드를 추가합니다. 🎜
    🎜역할 외에도(예: ROLE_ADMIN ), 다른 속성/문자열(예: EDIT)을 사용하여 자원을 보호하고 유권자 또는 Symfony의 ACL 시스템을 사용하여 자원을 효과적으로 만들 수도 있습니다. 이는 사용자 A가 개체 B(예: ID가 5인 제품)를 "편집"할 수 있는지 확인해야 할 때 유용합니다. 🎜액세스 제어 목록(ACL): 개별 데이터베이스 개체 보호🎜를 참조하세요. 🎜🎜🎜

    역할/역할

    사용자가 로그인하면 역할 세트(예: ROLE_ADMIN)를 받게 됩니다. 위의 예에서 이러한 역할(역할)은 security.yml에 하드 코딩되어 있습니다. 데이터베이스에서 사용자를 로드하는 경우 해당 사용자는 테이블 열에 저장되어야 합니다. ROLE_ADMIN)。在上例中,这些(roles)都被写死到 security.yml 中了。如果你从数据库中加载用户,它们应该存在了表的某一列中。

    你要分给一个用户的所有roles,一定要以 ROLE_ 前缀开始。否则,它们不会被Symfony的Security系统按常规方式来操作(除非使用高级手段,否则你把 FOO 这样的role分给一个用户,然后像 下面这样 去检查 FOO 是行不通的)。

    roles很简单,而且基本上都是你根据需要自行创造的字符串。例如,如果你打算限制访问你网站博客的admin部分,可以使用ROLE_BLOG_ADMIN 这个role来进行保护。role毋须在其他地方定义-你就可以开始用它了。

    确保每个用户至少有一个 角色,否则他们会被当作未验证之人。常见的做法就是给每个 普通用户一个 ROLE_USER

    你还可以指定role层级,此时,拥有某些roles意味着你同时拥有了其他的roles。

    添加代码以拒绝访问 

    要拒绝访问(deny access)某些东东,有两种方式可以实现:

    通过条件匹配来保护URL(access_control) 

    对程序的某一部分进行保护时的最基本方法是对URL进行完整的条件匹配。之前你已看到,任何匹配了正则表达式 ^/admin 的页面都需要 ROLE_ADMIN

    사용자에게 할당하려는 모든 역할은 ROLE_ 접두사로 시작해야 합니다 . 그렇지 않으면 Symfony의 보안 시스템에서 일반적인 방법으로 작동하지 않습니다(고급 수단을 사용하지 않는 한, 그렇지 않으면 사용자에게 FOO와 같은 역할을 할당한 다음 FOO를 확인하기 위한 다음
    은 작동하지 않습니다.)
    역할은 매우 간단하며 기본적으로 필요에 따라 생성하는 문자열입니다. 예를 들어, 웹사이트 블로그의 관리 섹션에 대한 액세스를 제한하려는 경우 ROLE_BLOG_ADMIN 역할을 사용하여 이를 보호할 수 있습니다. 역할은 다른 곳에서 정의할 필요가 없습니다. 그냥 사용하면 됩니다.
    각 사용자에게 최소한 하나 역할이 있는지 확인하세요. 그렇지 않으면 다음과 같이 처리됩니다. 알 수 없음 유효성을 검사하는 사람입니다. 일반적인 접근 방식은 모든 일반 사용자에게 ROLE_USER를 제공하는 것입니다.
    🎜이때 특정 역할을 소유한다는 것은 다른 역할도 소유한다는 것을 의미합니다. 🎜🎜액세스를 거부하는 코드 추가
    ¶🎜🎜🎜무언가에 대한 액세스를 거부하려면 두 가지 방법이 있습니다. 달성 방법: 🎜

    URL 보호를 위한 조건부 매칭 통과(access_control) ¶🎜

    🎜프로그램의 특정 부분을 보호하는 가장 기본적인 방법은 보호하는 것입니다. URL 완료 조건이 일치합니다. 이전에 본 것처럼 정규식 ^/admin과 일치하는 모든 페이지에는 ROLE_ADMIN이 필요합니다. 🎜
    // yay! Use this to see if the user is logged in// 耶!使用这个来查看用户是否已登陆if (!$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
        throw $this->createAccessDeniedException();} // boo :(. Never check for the User object to see if they're logged in// 哄!:(. 切勿通过检查User对象来判断用户是否已登陆if ($this->getUser()) { }
    PHP:<?php if ($view['security']->isGranted('IS_AUTHENTICATED_FULLY')): ?>
        <p>Username: <?php echo $app->getUser()->getUsername() ?></p><?php endif; ?>
    🎜🎜🎜🎜🎜
    Twig:{% if is_granted('IS_AUTHENTICATED_FULLY') %}
        <p>Username: {{ app.user.username }}</p>{% endif %}
    🎜🎜🎜🎜🎜

    전체 영역(URL이 속한)을 보호할 수 있는 것도 좋지만 컨트롤러의 특정 동작을 보호할 수도 있습니다.

    URL 일치 조건을 원하는 만큼 정의할 수 있습니다. 각 조건은 정규식입니다. 이지만 하나만 일치합니다. Symfony는 파일의 맨 위에서 보기 시작하고 access_control에서 URL과 일치하는 항목을 찾는 즉시 종료됩니다. access_control 中的某个入口与URL相匹配,就立即结束。

    PHP:// app/config/security.php$container->loadFromExtension('security', array(
        // ...     'firewalls' => array(
            'secured_area' => array(
                // ...
                'logout' => array('path' => '/logout', 'target' => '/'),
            ),
        ),));
    Twig:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>
            <!-- ... -->         <firewall name="secured_area">
                <!-- ... -->
                <logout path="/logout" target="/" />
            </firewall>
        </config></srv:container>
    YAML:# app/config/security.ymlsecurity:    # ...
        firewalls:
            secured_area:            # ...
                logout:
                    path:   /logout
                    target: /

    在path中加了一个 ^ 是指,仅当URL“按照正则条件那样起头”时,才会匹配到。例如,一个path若只有 /admin(不包含 ^)则会匹配到 /admin/foo 但同时也匹配了 /foo/admin 这种。

    理解access_control是如何工作的

    access_control 部分异常强大,但如果你不明白它的工作原理,它也会很危险(毕竟涉及到安全性)。 access_control 除了匹配URL,还可匹配IP地址、主机名和HTTP method。它也可以用于将用户重定向到 https 版本的URL条件中去。

    要了解这一切,参考 Security的access_control是如何工作的

    保护控制器和代码中的其他部分 

    在控制器中你可以轻松谢绝访问:

    PHP:// app/config/routing.phpuse Symfony\Component\Routing\RouteCollection;use Symfony\Component\Routing\Route; $collection = new RouteCollection();$collection->add('logout', new Route('/logout')); return $collection;

    两种情况下,一个特殊的 AccessDeniedException 会被抛出,这最终触发了Symfony内部的一个403 HTTP响应。

    就是这样!如果是尚未登录的用户,他们会被要求登录(如,重定向到登录页面)。如果他们已经 登录,但不具备 ROLE_ADMIN 角色,则会被显示403拒绝访问页面(此页可以 自定义)。如果他们已登录同时拥有正确的roles,代码就会继续执行。

    多亏了SensioFrameworkExtraBundle,你可以在控制器中使用annotations

    XML:<!-- app/config/routing.xml --><?xml version="1.0" encoding="UTF-8" ?><routes xmlns="http://Symfony.com/schema/routing"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://Symfony.com/schema/routing        http://Symfony.com/schema/routing/routing-1.0.xsd">     <route id="logout" path="/logout" /></routes>

    参考 FrameworkExtraBundle 以了解更多。

    模版中的访问控制 

    如果你想在模版中检查当前用户是否具有一个role,可以使用内置的 is_granted()

    YAML:# app/config/routing.ymllogout:
        path: /logout
    PHP:// app/config/security.php$container->loadFromExtension('security', array(
        // ...     'role_hierarchy' => array(
            'ROLE_ADMIN'       => 'ROLE_USER',
            'ROLE_SUPER_ADMIN' => array(
                'ROLE_ADMIN',
                'ROLE_ALLOWED_TO_SWITCH',
            ),
        ),));

    XML:<!-- app/config/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        http://Symfony.com/schema/dic/services/services-1.0.xsd">     <config>
            <!-- ... -->         <role id="ROLE_ADMIN">ROLE_USER</role>
            <role id="ROLE_SUPER_ADMIN">ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH</role>
        </config></srv:container>
    경로에 ^를 추가하면 URL이 "일반 조건에 따라 시작"되는 경우에만 일치한다는 의미입니다. 예를 들어, 경로에 /admin(^ 제외)만 포함된 경우 /admin/foo와 일치하지만 /도 일치합니다. foo/admin 이거요. #🎜🎜#

    access_control 작동 방식 이해

    # 🎜 🎜#access_control 부분은 엄청나게 강력하지만 어떻게 작동하는지 이해하지 못하면 위험할 수도 있습니다(결국 보안이 관련됩니다). access_control URL 일치 외에도 IP 주소, 호스트 이름 및 HTTP 메서드도 일치시킬 수 있습니다. 또한 사용자를 https 버전의 URL 조건으로 리디렉션하는 데 사용할 수도 있습니다. #🎜🎜##🎜🎜#이 모든 내용을 이해하려면 보안의 access_control 작동 방식#🎜🎜#을 참조하세요. #🎜🎜##🎜🎜##🎜🎜#

    컨트롤러와 코드의 다른 부분을 보호하세요 ¶#🎜🎜##🎜🎜#컨트롤러에서 액세스를 쉽게 거부할 수 있습니다. #🎜🎜#
    YAML:# app/config/security.ymlsecurity:    # ...
        role_hierarchy:
            ROLE_ADMIN:       ROLE_USER
            ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
    #🎜🎜#두 경우 모두 특별한
    AccessDeniedException#🎜🎜#가 발생하여 궁극적으로 내부 Symfony A 403 HTTP 응답이 트리거됩니다.
    #🎜🎜##🎜🎜#그렇습니다! 사용자가 아직 로그인하지 않은 경우 로그인하라는 메시지가 표시됩니다(예: 로그인 페이지로 리디렉션됨). 이미 로그인했지만 ROLE_ADMIN 역할이 없는 경우 403 액세스 거부 페이지가 표시됩니다(이 페이지는
    사용자 정의 #🎜🎜#). 로그인되어 있고 올바른 역할이 있으면 코드가 계속 실행됩니다. #🎜🎜##🎜🎜# SensioFrameworkExtraBundle 덕분에 컨트롤러에서 주석을 사용할 수 있습니다#🎜🎜#rrreee#🎜🎜#ReferenceFrameworkExtraBundle#🎜🎜# 자세히 알아보기
    #🎜🎜#

    템플릿의 액세스 제어 ¶#🎜🎜#

    #🎜🎜#If you If 현재 사용자에게 템플릿에 역할이 있는지 확인하려면 내장된 is_granted() 도우미 함수를 사용할 수 있습니다. #🎜🎜#rrreee#🎜🎜#rrreee#🎜🎜#

    다른 서비스 보호

    "Protect Controller"와 같은 유사한 코드를 작성하면 Symfony 내 어디든 보호할 수 있습니다. 이메일을 보내기 위한 서비스(예: PHP 클래스)가 있다고 가정해 보겠습니다. 이 클래스의 사용을 - 사용 위치에 관계없이 - 특정 사용자로만 제한할 수 있습니다.

    자세한 내용은 프로그램에서 서비스 및 메서드를 보호하는 방법을 참조하세요.

    사용자가 로그인했는지 확인하세요(IS_AUTHENTICATED_FULLY)

    지금까지 역할 기반 액세스, 즉 사용자에게 할당된 ROLE_ 접두사로 시작하는 문자열을 확인했습니다. 하지만 ROLE_ 前缀开头的字符串,被分配给了用户。但是,如果你 想检查用户是否登录(并不关心什么role不role的),那么你可以使用 IS_AUTHENTICATED_FULLY// ... public function helloAction($name){

    rrreee

    你当然也可以使用在 access_control 中使用它。

    IS_AUTHENTICATED_FULLY 不是一个role,但是它的某些行为又像是role,并且每个成功登录的用户都有这么一个。事实上,类似的特殊属性共有三个: