在允许用户访问系统之前,我要在我想要验证的 URL 中发送一个 hmac。没有用户数据库,因此它只是验证 url 参数以验证它是由正确的服务器生成的,用户无法更改这些参数来访问系统的其他部分。
我想知道是否有人对 SecurityServiceProvider 做过类似的事情。我可以使用在路由和安全防火墙规则之后触发的 before 中间件来执行此操作。如果可能的话,我想在防火墙上停止这个请求。
我决定“之前”使用 silex 的中间件功能。我确定这可能不是解决此问题的最佳方法,但我的应用程序没有用户或身份验证,所以我只需要检查密钥是否正确并返回响应。如果有人对改进这一点有任何意见,我很想听听他们的意见。
当外部系统生成 url 时,它们必须使用我的配置文件中定义的共享密钥,并且可以通过 $app['config']['hmac_key'] 访问。hmac 是在路径中 hmac 之后的所有内容上生成的。所以如果我有子文件夹 domain.com/folder/hmac/arg1/arg2/arg3。before 过滤器在 hmac 处拆分路由并在此之后构建路径。
// Before firing the controller check the hmac matches, otherwise return 403.
$app->before(function (Request $request) use ($app) {
// 40 chars in a sha1 hmac hash
if(!preg_match('/^[0-9a-f]{40}$/i', $request->get('hmac')))
$app->abort(403, "Invalid key.");
// break the route down to the arguments used in hmac
$route = explode('hmac_', $request->get('_route'));
$route = explode('_',$route[1]);
// build the path used to generate hmac
$path = array();
foreach($route as $r)
if($v = $request->get($r))
$path[] = $v;
$path = implode('/', $path);
// Generate hmac hash from path and key
$hmac = hash_hmac("sha1", $path, $app['config']['hmac_key']);
// If the hmac's don't match return 403
if($hmac !== $request->get('hmac'))
$app->abort(403, "Invalid key.");
});