在非安全(匿名)路由上显示经过身份验证的用户

问题描述:

I use PHP and Silex to build a web app and I implemented basic authentication via SecurityServiceProvider like this:

$app->register(new Silex\Provider\SecurityServiceProvider(), array(
    'security.firewalls' => array(
        'private' => array(
            'remember_me' => array(
                'key' => $config['secret_key'],
                'lifetime' => $config['remember_me_duration'],
            ),
            'pattern' => '^/admin',
            'form' => array('login_path' => '/login', 'check_path' => '/admin/login_check'),
            'logout' => array('logout_path' => '/admin/logout'),
            'users' => $app->share(function () use ($app) {
                // ...
            }),
        ),
        'public' => array(
            'pattern' => '^/$',
            'anonymous' => true,
        ),
        'login' => array(
            'pattern' => '^/login$',
            'anonymous' => true,
        ),
    ),
));

As you can see the /admin paths are secured, there I can use $app['security']->getToken()->getUser(); to get the actual user that is authenticated and display something like Logged in as $username, but if I do this on the /login or / routes the user will always be anon. even if I'm authenticated.

How can I get the authenticated user, if there is one, otherwise the anon. string, on the / and /login routes in order to display a message like: Logged in as $username ?

I also tried to use is_granted('IS_AUTHENTICATED_FULLY' function in the twig templates to check if the user is authenticated, but on /login and / it returns false (even if I'm authenticated) since the anonymous user takes precedence over the authenticated ones, so no success here.

我使用PHP和Silex构建Web应用程序,并通过 SecurityServiceProvider code>实现了基本身份验证 像这样: p>

  $ app-> register(new Silex \ Provider \ SecurityServiceProvider(),array(
'security.firewalls'=> array(
')  private'=> array(
'remember_me'=> array(
'key'=> $ config ['secret_key'],
'lifetime'=> $ config ['remember_me_duration'],\  n),
'pattern'=>'^ / admin',
'form'=> array('login_path'=>'/ login','check_path'=>'/ admin / login_check'  ),
'logout'=>数组('logout_path'=>'/ admin / logout'),
'users'=> $ app-> share(function()use($ app){  
 // ... 
}),
),
'public'=> array(
'pattern'=>'^ / $',
'匿名'=> true,  
),
'login'=>数组(
  'pattern'=>  '^ / login $',
'匿名'=>  true,
),
),
)); 
  code>  pre> 
 
 

正如您所见, / admin code>路径是安全的, 在那里,我可以使用 $ app ['security'] - > getToken() - > getUser(); code>来获取经过身份验证的实际用户,并显示类似登录为$的内容 用户名 em>,但如果我在 / login code>或 / code>路由上执行此操作,则用户将始终是 anon。 code>,即使我' 经过身份验证。 p>

我如何获得经过身份验证的用户,如果有的话, / code>上的 anon。 code>字符串 和 / login code>路由以显示如下消息:以$ username em>登录? p>

我还尝试使用 is_granted('IS_AUTHENTICATED_FULLY' code>函数来检查用户是否经过身份验证,但在 / login code>和 / code>上它返回false(即使我 '经过身份验证)因为匿名用户优先于经过身份验证的用户,所以这里没有成功。 p>

Everything must be under the same firewall and you have to use access control.

In order to help other people, I solved the issue as described below. Silex doesn't use access_control, but access_rules (dammit).

As Pazi (+1ed) suggested I combined everything under a single firewall and used access_rules:

$app->register(new Silex\Provider\SecurityServiceProvider(), array(
    'security.firewalls' => array(
        'main' => array(
            'remember_me' => array(
                'key' => $config['secret_key'],
                'lifetime' => $config['remember_me_duration'],
            ),
            'pattern' => '^/',
            'anonymous' => true,
            'form' => array(
                'login_path' => '/login',
                'check_path' => '/admin/login_check',
            ),
            'logout' => array('logout_path' => '/admin/logout'),
            'users' => $app->share(function () use ($app) {
                // ...
            }),
        ),
    ),
    'security.access_rules' => array(array('^/admin/files', 'ROLE_ADMIN'),
    ),
));

@Paul I'd prefer to add the comment but I can't do it yet, so as an answer than:

It looks like taking out

'pattern' => '^/admin'

string from the firewall pattern you have opened anonymous access to the /admin/login_check, and this is not right.

My suggestion is to take it back and remove

'anonymous' => 'true'

line from the firewall. Should work the same but would be more secured.