最近刚刚好在看Silex文档,就按照自己的理解做了下笔记,蹩脚翻译请轻拍。
SecurityServiceProvider类 负责管理你的应用中的鉴定和
授权功能。
参数:
security.hide_user_not_found (optional):
定义是否隐藏用户没有找到的exception,默认为真
security.encoder.bcrypt.cost (optional):
定义 BCrypt password encoder cost,默认为13
security.token_storage:
得到指向用户密钥的连接
security.encoder_factory:
定义用户密码的加密策略
服务:
service provider定义了许多其他的内置服务,几乎无须再自定义。
注册:
$app->register(new Silex\Provider\SecurityServiceProvider(), array(
‘security.firewalls’ => // see below
));
添加symfony security 组建作为依赖 composer require symfony/security
如果是用表单来鉴定用户信息,需要引用 SessionServiceProvider.
使用:
详细信息看symfony安全性文档
通过日志信息调试问题
下面是一些用例谱,包含了一些通用的使用情况
1/访问当前用户
当前的用户信息存储在一个token(密钥)中 ,通过安全服务易于访问。
$token = $app['security.token_storage']->getToken();
如果没有当前用户信息,则token是空的,否则你可用通过getUser()来得到用户信息
if (null !== $token) {
$user = $token->getUser();
}
用户信息可以是 string ,含有_toString()函数的对象,继承自用户接口的实例
2/通过HTTP验证锁定路径
$app['security.firewalls'] = array(
'admin' => array(
'pattern' => '^/admin',
'http' => true,
'users' => array(
// raw password is foo
'admin' => array('ROLE_ADMIN', '$2y$10$3i9/lVd8UOFIJ6PAMFt8gu3/r5g0qeCJvoSlLCsvMTythye19F77a'),
),
),
);
如果你想通过更多的方式来设定防火墙,使用RequestMatcher类的实例来设定
use Symfony/Component/HttpFoundation/RequestMatcher;
$app['security.firewalls'] = array(
'admin' => array(
'pattern' => new RequestMatcher('^/admin', 'example.com', 'POST'),
// ...
),
);
每个用户都由如下信息定义:
!The role or an array of roles for the user (roles are strings beginning with ROLE_ and ending with anything you want);
!The user encoded password.用户加密密码
默认的扩展配置为强制执行加密密码,为了从原生的密码中得到有效的加密密码,使用security.encoder_factory服务
// 找到用户接口实例的编码器
$encoder = $app['security.encoder_factory']->getEncoder($user);
// 为‘foo’计算加密密码
$password = $encoder->encodePassword('foo', $user->getSalt());
当用户验证通过,User将被作为一个User的实例存储在Token中。
3/通过表单锁定路径
通过表单来验证用户和之前的配置相似。使用一个表单和2个参数来代替使用http设定。
login_path:
check_path: symfony使用验证路径来校验用户证书
$app['security.firewalls'] = array(
'admin' => array(
'pattern' => '^/admin/',
'form' => array('login_path' => '/login', 'check_path' => '/admin/login_check'),
'users' => array(
'admin' => array('ROLE_ADMIN', '$2y$10$3i9/lVd8UOFIJ6PAMFt8gu3/r5g0qeCJvoSlLCsvMTythye19F77a'),
),
),
);
记住两个黄金法则:
login_path必须被定义在安全地区之外,否则则需激活匿名验证规则。
check_path必须被定义在安全地区之内。
首先建立如下的控制器来保证登录表单正常工作:
use Symfony\Component\HttpFoundation\Request;
$app->get('/login', function(Request $request) use ($app) {
return $app['twig']->render('login.html', array(
'error' => $app['security.last_error']($request),
'last_username' => $app['session']->get('_security.last_username'),
));
});
error and last_username 变量包涵了上次验证错误和上次进入用户的用户名
创建关联模板:
<form action="{{ path('admin_login_check') }}" method="post">
{{ error }}
<input type="text" name="_username" value="{{ last_username }}" />
<input type="password" name="_password" value="" />
<input type="submit" />
</form>
注:admin_login_check路由在silex中自动被定义its name is 派生 from the check_path value。
4/定义多个防火墙
当你想用不同的验证策略来保护你的站点的不同部分或不同的用户时(like using an HTTP basic authentication for the website API and a form to secure your website administration area,配置多个防火墙很有用。
当你想要保护除login外的所有url时也很有用:
$app['security.firewalls'] = array(
'login' => array(
'pattern' => '^/login$',
),
'secured' => array(
'pattern' => '^.*$',
'form' => array('login_path' => '/login', 'check_path' => '/login_check'),
'users' => array(
'admin' => array('ROLE_ADMIN', '$2y$10$3i9/lVd8UOFIJ6PAMFt8gu3/r5g0qeCJvoSlLCsvMTythye19F77a'),
),
),
);
5/添加登出
$app['security.firewalls'] = array(
'secured' => array(
'pattern' => '^/admin/',
'form' => array('login_path' => '/login', 'check_path' => '/admin/login_check'),
'logout' => array('logout_path' => '/admin/logout', 'invalidate_session' => true),
// ...
),
);
一个路由自动生成(基于配置路径)
<a href="{{ path('admin_logout') }}">Logout</a>
6/允许匿名用户
当只保护部分你的站点路由时,用户信息在非保护地区无用,为了让用户易于访问这些非保护地区,激活匿名验证原则。
$app['security.firewalls'] = array(
'unsecured' => array(
'anonymous' => true,
// ...
),
);
当启用匿名设定时,一个用户从安全环境可直接进入,如果用户没有被验证,则返回一个anon.string。
7/检查用户角色
在安全环境中使用isGranted()方法验证用户是否是某一角色:
if ($app['security.authorization_checker']->isGranted('ROLE_ADMIN')) {
// ...
}
同时也可在twig模板中使用:
{% if is_granted('ROLE_ADMIN') %}
<a href="/secured?_switch_user=fabien">Switch to Fabien</a>
{% endif %}
You can check if a user is "fully authenticated" (not an anonymous user for instance) with the special IS_AUTHENTICATED_FULLY role:
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
<a href="{{ path('logout') }}">Logout</a>
{% else %}
<a href="{{ path('login') }}">Login</a>
{% endif %}
Of course you will need to define a login route for this to work.