SecurityBundle配置信息("security"根键)

3.3 版本
维护中的版本

security系统是Symfony框架最为强力的部分之一,且可利用其配置文件进行很大程度上的控制。

完整的默认配置 

下面是安全系统的全部默认配置。其中的每一部分都将在后面小节中进行解释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# app/config/security.yml
security:
    access_denied_url:    ~ # Example: /foo/error403
 
    # strategy can be: none, migrate, invalidate
    # 策略可以是:none, migrate, invalidate
    session_fixation_strategy:  migrate
    hide_user_not_found:  true
    always_authenticate_before_granting:  false
    erase_credentials:    true
    access_decision_manager:
        strategy:             affirmative # One of affirmative, consensus, unanimous
        allow_if_all_abstain:  false
        allow_if_equal_granted_denied:  true
    acl:

        # any name configured in doctrine.dbal section
        # 可以是在doctrine.dbal区块中进行了配置的任何名字
        connection:           ~
        cache:
            id:                   ~
            prefix:               sf2_acl_
        provider:             ~
        tables:
            class:                acl_classes
            entry:                acl_entries
            object_identity:      acl_object_identities
            object_identity_ancestors:  acl_object_identity_ancestors
            security_identity:    acl_security_identities
        voter:
            allow_if_object_identity_unavailable:  true

    encoders:
        # Examples/使用样例:
        Acme\DemoBundle\Entity\User1: sha512
        Acme\DemoBundle\Entity\User2:
            algorithm:           sha512
            encode_as_base64:    true
            iterations:          5000
 
        # PBKDF2 encoder
        # see the note about PBKDF2 below for details on security and speed
        # 参考下面的PBKDF2相关注释以了解“安全性和速度”的细节
        Acme\Your\Class\Name:
            algorithm:            pbkdf2
            hash_algorithm:       sha512
            encode_as_base64:     true
            iterations:           1000
            key_length:           40
 
        # Example options/values for what a custom encoder might look like
        # 关于自定义加密器的“键/值”配置样例:
        Acme\DemoBundle\Entity\User3:
            id:                   my.encoder.id
 
        # BCrypt encoder
        # see the note about bcrypt below for details on specific dependencies
        # 参考下面的bcrypt相关注释以了解“特定依赖”的细节
        Acme\DemoBundle\Entity\User4:
            algorithm:            bcrypt
            cost:                 13
 
        # Plaintext encoder
        # it does not do any encoding 它并不进行任何加密动作
        Acme\DemoBundle\Entity\User5:
            algorithm:            plaintext
            ignore_case:          false

    providers:            # Required / 必选项
        # Examples:
        my_in_memory_provider:
            memory:
                users:
                    foo:
                        password:           foo
                        roles:              ROLE_USER
                    bar:
                        password:           bar
                        roles:              [ROLE_USER, ROLE_ADMIN]

        my_entity_provider:
            entity:
                class:              SecurityBundle:User
                property:           username
                # name of a non-default entity manager
                manager_name:       ~

        my_ldap_provider:
            ldap:
                service:            ~
                base_dn:            ~
                search_dn:          ~
                search_password:    ~
                default_roles:      'ROLE_USER'
                uid_key:            'sAMAccountName'
                filter:             '({uid_key}={username})'
 
        # Example custom provider 自定义user provider的使用样例
        my_some_custom_provider:
            id:                   ~
 
        # Chain some providers / user provider的链式用法(译注:很重要)
        my_chain_provider:
            chain:
                providers:          [ my_in_memory_provider, my_entity_provider ]

    firewalls:            # Required / 必选项
        # Examples:
        somename:
            pattern: .*
            # restrict the firewall to a specific host
            # 限制防火墙运行在指定host之下
            host: admin\.example\.com
            # restrict the firewall to specific http methods
            # 限制防火墙运行在指定的http方法之下
            methods: [GET, POST]
            request_matcher: some.service.id
            access_denied_url: /foo/error403
            access_denied_handler: some.service.id
            entry_point: some.service.id
            provider: some_key_from_above
            # manages where each firewall stores session information
            # 管理每个防火墙存储session信息时的位置
            # See "Firewall Context" below for more details
            # 参考下面的“防火墙上下文”来了解细节
            context: context_key
            stateless: false
            x509:
                provider: some_key_from_above
            remote_user:
                provider: some_key_from_above
            http_basic:
                provider: some_key_from_above
            http_basic_ldap:
                provider:  some_key_from_above
                service:   ldap
                dn_string: '{username}'
            http_digest:
                provider: some_key_from_above
            guard:
                # A key from the "providers" section of your security config, in case your user provider is different than the firewall
                # 这个键来自于你的安全配置中的“providers”区块,如果你的user provider与防火墙中的并不相同的话
                provider:             ~
 
                # A service id (of one of your authenticators) whose start() method should be called when an anonymous user hits a page that requires authentication
                # 一个服务定义id(你的某个authenticator),其start()方法应该在anonymous用户命中“一个需要认证”的页面后被调用
                entry_point:          null
 
                # An array of service ids for all of your "authenticators"
                # 一个由“你的所有authenticator之服务定义id”所组成的数组
                authenticators:       []
            form_login:
                # submit the login form here / 在这里提交表单登录
                check_path: /login_check
 
                # the user is redirected here when they need to log in
                # 当用户需要登录时,将其跳转到这里
                login_path: /login
 
                # if true, forward the user to the login form instead of redirecting
                # 若为true,将用户推送到登录表单而不是重定向(译注:forward是Symfony路由功能之一)
                use_forward: false
 
                # login success redirecting options (read further below)
                # 登录成功后的跳转选项(下文有解释)
                always_use_default_target_path: false
                default_target_path:            /
                target_path_parameter:          _target_path
                use_referer:                    false
 
                # login failure redirecting options (read further below)
                # 登录失败后的跳转选项(下文有解释)
                failure_path:    /foo
                failure_forward: false
                failure_path_parameter: _failure_path
                failure_handler: some.service.id
                success_handler: some.service.id
 
                # field names for the username and password fields
                # 用户名和密码两个字段的表单变量名
                username_parameter: _username
                password_parameter: _password
 
                # csrf token options / csrf token选项
                csrf_parameter:       _csrf_token
                csrf_token_id:        authenticate
                csrf_token_generator: my.csrf_token_generator.id
 
                # by default, the login form *must* be a POST, not a GET
                # 默认时,登录表单 *必须* 是POST方式,不能是GET
                post_only:      true
                remember_me:    false
 
                # by default, a session must exist before submitting an authentication request
                # if false, then Request::hasPreviousSession is not called during authentication
                # 默认是,session必须在提前一个authentication请求之前已经存在
                # 否则的话,Request::hasPreviousSession在认证过程中将不被调用
                require_previous_session: true

            form_login_ldap:
                # submit the login form here / 在这里提交表单登录
                check_path: /login_check
 
                # the user is redirected here when they need to log in
                # 当用户需要登录时,将其跳转到这里
                login_path: /login
 
                # if true, forward the user to the login form instead of redirecting
                # 若为true,将用户推送到登录表单而不是重定向(译注:forward是Symfony路由功能之一)
                use_forward: false
 
                # login success redirecting options (read further below)
                # 登录成功后的跳转选项(下文有解释)
                always_use_default_target_path: false
                default_target_path:            /
                target_path_parameter:          _target_path
                use_referer:                    false
 
                # login failure redirecting options (read further below)
                # 登录失败后的跳转选项(下文有解释)
                failure_path:    /foo
                failure_forward: false
                failure_path_parameter: _failure_path
                failure_handler: some.service.id
                success_handler: some.service.id
 
                # field names for the username and password fields
                # 填写用户名和密码两个字段的表单变量名
                username_parameter: _username
                password_parameter: _password
 
                # csrf token options / csrf token选项
                csrf_parameter:       _csrf_token
                csrf_token_id:        authenticate
                csrf_token_generator: my.csrf_token_generator.id
 
                # by default, the login form *must* be a POST, not a GET
                # 默认时,登录表单 *必须* 是POST方式,不能是GET
                post_only:      true
                remember_me:    false
 
                # by default, a session must exist before submitting an authentication request
                # if false, then Request::hasPreviousSession is not called during authentication
                # new in Symfony 2.3
                # 默认是,session必须在提前一个authentication请求之前已经存在
                # 否则的话,Request::hasPreviousSession在认证过程中将不被调用
                # 这是Symofny 2.3的新功能
                require_previous_session: true

                service:   ~
                dn_string: '{username}'

            remember_me:
                token_provider: name
                secret: "%secret%"
                name: NameOfTheCookie
                lifetime: 3600 # in seconds
                path: /foo
                domain: somedomain.foo
                secure: false
                httponly: true
                always_remember_me: false
                remember_me_parameter: _remember_me
            logout:
                path:   /logout
                target: /
                invalidate_session: false
                delete_cookies:
                    a: { path: null, domain: null }
                    b: { path: null, domain: null }
                handlers: [some.service.id, another.service.id]
                success_handler: some.service.id
            anonymous: ~
 
        # Default values and options for any firewall
        # 任意防火墙的默认选项(键)和选项值
        some_firewall_listener:
            pattern:              ~
            security:             true
            request_matcher:      ~
            access_denied_url:    ~
            access_denied_handler:  ~
            entry_point:          ~
            provider:             ~
            stateless:            false
            context:              ~
            logout:
                csrf_parameter:       _csrf_token
                csrf_token_generator: ~
                csrf_token_id:        logout
                path:                 /logout
                target:               /
                success_handler:      ~
                invalidate_session:   true
                delete_cookies:

                    # Prototype
                    name:
                        path:                 ~
                        domain:               ~
                handlers:             []
            anonymous:
                secret:               "%secret%"
            switch_user:
                provider:             ~
                parameter:            _switch_user
                role:                 ROLE_ALLOWED_TO_SWITCH

    access_control:
        requires_channel:     ~
 
        # use the urldecoded format 使用 urldecoded反加密格式路径
        path:                 ~ # Example: ^/path to resource/
        host:                 ~
        ips:                  []
        methods:              []
        roles:                []
    role_hierarchy:
        ROLE_ADMIN:      [ROLE_ORGANIZER, ROLE_USER]
        ROLE_SUPERADMIN: [ROLE_ADMIN]

表单登录配置 

当使用form_login这个位于防火墙下面(firewall键之下)的authentication listener(认证监听器)时,有几个常规选项,用来配置“表单登录”的体验。

更多细节,参考如何配置你的表单登陆一文。

登录表单及其处理进程 

login_path 

值类型string 默认值/login

这是用户在尝试访问一个受保护的资源但却没有被“完全认证(fully authenticated)”时,应该被重定向到某处的路由或路径(除非use_forward被设为true)。

此处的路径必须是一个普通的非认证用户可以访问到的,否则你就进入了一个重定向的死循环,参考“避免常见陷阱”。

check_path 

值类型string 默认值/login_check

这是你的表单所必须提交的某处页面的路由或路径。防火墙将拦截任何对此URL的请求(默认时只针对POST请求),并处理提交过来的登录凭据(credentials)。

确保这个链接被你的主防火墙所覆盖(即,不要仅为check_path URL创建一个独立的防火墙)

use_forward 

值类型boolean 默认值false

如果你希望用户被foward(推送)到登录表单而不是被重定向到那里,设置此选项为true

username_parameter 

值类型string 默认值_username

这是你应该给予的登陆表单之“用户名”字段的变量名字。当你提交表单到check_path时,security系统会在POST参数中寻找这个名字。

password_parameter 

值类型string 默认值_password

这是你应该给予的登陆表单之“用户名”字段的变量名字。当你提交表单到check_path时,security系统会在POST参数中寻找这个名字。

post_only 

值类型boolean 默认值true

默认时,你必须以POST请求来将登录表单提交到check_path。设置此选项为false,即可发送GET请求到check_path URL了。

登录后的重定向 

  • always_use_default_target_path(值类型:boolean,默认值false

  • default_target_path(值类型:string,默认值/

  • target_path_parameter(值类型:string,默认值_target_path

  • use_referer(值类型:boolean,默认值false

Logout配置 

invalidate_session 

值类型boolean 默认值true

默认时,当用户从防火墙中登出时,其session将会失效。这意味着从一个防火墙登出,也将自动从其他所有防火墙中登出。

invalidate_session选项允许重新定义此种行为。在每一个防火墙中都将此选项设置为false,则用户只能从当前防火墙中退出,而不会影响到其他的。

LDAP功能 

有几个选项是用于连接LDAP服务器的,使用form_login_ldaphttp_basic_ldap authentication providers配合ldap user provider。

更多细节请参考 针对LDAP服务器进行身份认证

authentication/认证 

你可以对一台LDAP服务器进行认证,使用诸如form_loginhttp_basic等authentication providers的LDAP变体即可。只需使用form_login_ldaphttp_basic_ldap,即可尝试bind(绑定)某台LDAP服务器,而不是使用密码比对(password comparison)。

service 

值类型string 默认值ldap

这是你配置的LDAP客户端的名字。

dn_string 

值类型string 默认值{username}

这是个字符串,将用于DN绑定。{username}占位符将被替换成“由用户提供的”值(即他的登录)。根据你LDAP服务器的配置,你也许需要覆写这个值。

User provider 

用户的取出仍然是从已配置的user provider中进行。如果你希望从一台LDAP服务器上取出用户,你需要使用ldap user provider,此外还要配合以下两种authentication provider之一(form_login_ldaphttp_basic_ldap)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# app/config/security.yml
security:
    # ...

    providers:
        my_ldap_users:
            ldap:
                service: ldap
                base_dn: "dc=symfony,dc=com"
                search_dn: "%ldap.search_dn%"
                search_password: "%ldap.search_password%'
                default_roles: ""
                uid_key: "uid"
                filter: "(&({uid_key}={username})(objectclass=person)(ou=Users))"

使用PBKDF2 Encoder:安全性和速度 

PBKDF2加密器,提供了一种高级别的密码学安全性,被National Institute of Standards and Technology (NIST)(美国国家标准及技术研究所)推荐。

在本页的YAML配置区块中,你可以看到一个pbkdf2 encoder的示例。

但是使用PBKDF2也带来了一个警告:使用它(以一个较大的迭代数字)会拖慢(加密)进程。因此,在使用PBKDF2时要特别警惕和小心。

一个较好的配置,应该设成至少1000次迭代(iterations),并且使用shar512作为hash算法。

使用BCryptPassword Encoder 

1
2
3
4
5
6
7
8
# app/config/security.yml
security:
    # ...

    encoders:
        Symfony\Component\Security\Core\User\User:
            algorithm: bcrypt
            cost:      15
1
2
3
4
5
6
7
8
9
<!-- app/config/security.xml -->
<config>
    <!-- ... -->
    <encoder
        class="Symfony\Component\Security\Core\User\User"
        algorithm="bcrypt"
        cost="15"
    />
</config>
1
2
3
4
5
6
7
8
9
10
// app/config/security.php
$container->loadFromExtension('security', array(
    // ...
    'encoders' => array(
        'Symfony\Component\Security\Core\User\User' => array(
            'algorithm' => 'bcrypt',
            'cost'      => 15,
        ),
    ),
));

cost取值可以是4-31,它决定的是一个密码被加密时所耗费的时长。cost的每一次递增,会双倍耗费它加密密码的时间。

如果你没有提供cost选项,默认使用的取值是13

你可以在随时改变cost值——甚至你已经有了用另外一个cost值来加密的密码。新密码将使用新值来加密,而既存的密码,将通过使用“之前它们被加密时的cost”来验证。

每一个新密码都会自动地生成一个salt值,并不需要被持久化(译注:persisting,入库)。因为一个被加密过的密码,已经包含了这个“用作加密”的salt,仅对密码本身进行持久化已经足够。

所有加密的密码都是60个字符的长度,所以请确保划分出足够的空间来对其进行持久化。

Firewall Context/防火墙上下文 

多数程序只需一个firewall即防火墙。但如果你的程序确实需要使用多个防火墙,你需要注意一下,如果你正在一个防火墙里面进行认证,你将不会自动地在另外一个防火墙里展开认证。换句话说,系统并不去共享一个通常所说的“context”(上下文):每一个防火墙如同工作在一个独立的安全系统之中。

然而,每一个防火墙都有一个可选的context键(其默认值就是它所在的防火墙的名字),在向session存入/取出“security数据”时,它要被用到。如果这个键在多个防火墙中被设置为同一个名字,则“context”将被真切地“共享”:

1
2
3
4
5
6
7
8
9
10
11
# app/config/security.yml
security:
    # ...

    firewalls:
        somename:
            # ...
            context: my_context
        othername:
            # ...
            context: my_context
1
2
3
4
5
6
7
8
9
<!-- app/config/security.xml -->
<security:config>
    <firewall name="somename" context="my_context">
        <! ... ->
    </firewall>
    <firewall name="othername" context="my_context">
        <! ... ->
    </firewall>
</security:config>
1
2
3
4
5
6
7
8
9
10
11
12
13
// app/config/security.php
$container->loadFromExtension('security', array(
    'firewalls' => array(
        'somename' => array(
            // ...
            'context' => 'my_context'
        ),
        'othername' => array(
            // ...
            'context' => 'my_context'
        ),
    ),
));

HTTP-Digest认证 

使用HTTP-Digest认证,你需要提供一个realm(范围)和一个secret(密钥):

1
2
3
4
5
6
7
# app/config/security.yml
security:
    firewalls:
        somename:
            http_digest:
                secret: "%secret%"
                realm: 'secure-api'
1
2
3
4
5
6
<!-- app/config/security.xml -->
<security:config>
    <firewall name="somename">
        <http-digest secret="%secret%" realm="secure-api" />
    </firewall>
</security:config>
1
2
3
4
5
6
7
8
9
10
11
// app/config/security.php
$container->loadFromExtension('security', array(
    'firewalls' => array(
        'somename' => array(
            'http_digest' => array(
                'secret' => '%secret%',
                'realm'  => 'secure-api',
            ),
        ),
    ),
));

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)