如何检查用户是否已在控制器内登录Symfony2?


75

在这里阅读如何在基于Symfony2的网站的树枝模板内部检查用户的登录状态。但是,我需要知道如何检查用户是否从控制器内部登录。我很确定以下代码正确:

$user = $this->get('security.context')->getToken()->getUser();

但它总是返回一些信息,例如,登录用户或匿名用户。

任何想法?提前致谢。


您不能检查$ user!=“ anon”吗?
洛伦佐·马尔孔

好吧,我正在寻找更“安全”的东西。不是另一种方法,即调用某些函数吗?
JeanValjean 2012年

Answers:


150

警告'IS_AUTHENTICATED_FULLY'如果用户使用“记住我”功能登录,则单独检查将返回false。

根据Symfony 2文档,有3种可能性:

IS_AUTHENTICATED_ANONYMOUSLY-自动分配给位于站点受防火墙保护的部分但尚未实际登录的用户。仅在允许匿名访问的情况下,这才可能。

IS_AUTHENTICATED_REMEMBERED-自动分配给通过“记住我” cookie进行身份验证的用户。

IS_AUTHENTICATED_FULLY-自动分配给在当前会话期间提供了登录详细信息的用户。

这些角色代表三种身份验证级别:

如果您具有IS_AUTHENTICATED_REMEMBERED角色,那么您也将具有IS_AUTHENTICATED_ANONYMOUSLY角色。如果您具有 IS_AUTHENTICATED_FULLY角色,那么您还将具有其他两个角色。换句话说,这些角色代表了提高身份验证“强度”的三个级别。

我遇到了一个问题,即使用“记住我”功能的系统用户被视为根本没有在仅检查的页面上登录'IS_AUTHENTICATED_FULLY'

答案是要求他们如果没有通过完整的身份验证,则重新登录,或者检查记住的角色:

$securityContext = $this->container->get('security.authorization_checker');
if ($securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
    // authenticated REMEMBERED, FULLY will imply REMEMBERED (NON anonymous)
}

希望这可以避免有人犯同样的错误。在查找如何检查是否有人登录Symfony 2时,我以这篇文章作为参考。

来源:http : //symfony.com/doc/2.3/cookbook/security/remember_me.html#forcing-the-user-to-re-authenticate-before-accessing-certain-resources


4
实际上,您可以只使用$securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED'),因为角色是分层的。因此具有IS_AUTHENTICATED_FULLY暗示用户也具有IS_AUTHENTICATED_REMEMBERED
theunraveler 2012年

3
不对。仅当用户使用“记住我”功能时,IS_AUTHENTICATED_REMEMBERED才返回true。拥有IS_AUTHENTICATED_FULLY确实意味着IS_AUTHENTICATED_REMEMBERED,但并非相反。
布赖森2012年

4
对。如果IS_AUTHENTICATED_FULLY还保证用户拥有IS_AUTHENTICATED_REMEMBERED,那么您只需要检查IS_AUTHENTICATED_REMEMBERED
theunraveler 2012年

1
当您拥有不同的角色时,该如何处理。例如,对于站点的某些区域,我有一个ROLE_USER和ROLE_ADMIN,我想允许这两种类型的用户以IS_AUTHENTICATED_REMEMBERED级别访问他们各自的区域。我该怎么做?
尼克

2
顺便说一句,$this->container->get('security.authorization_checker')改用(2.6中的新功能)
罗南2015年

56

SecurityContext将在以下版本中弃用 Symfony 3.0

Symfony 2.6您使用之前SecurityContext
SecurityContext将不赞成Symfony 3.0赞成AuthorizationChecker

对于Symfony 2.6+Symfony 3.0使用AuthorizationChecker


Symfony 2.6(及以下)

// Get our Security Context Object - [deprecated in 3.0]
$security_context = $this->get('security.context');
# e.g: $security_context->isGranted('ROLE_ADMIN');

// Get our Token (representing the currently logged in user)
$security_token = $security_context->getToken();
# e.g: $security_token->getUser();
# e.g: $security_token->isAuthenticated();
# [Careful]             ^ "Anonymous users are technically authenticated"

// Get our user from that security_token
$user = $security_token->getUser();
# e.g: $user->getEmail(); $user->isSuperAdmin(); $user->hasRole();

// Check for Roles on the $security_context
$isRoleAdmin = $security_context->isGranted('ROLE_ADMIN');
# e.g: (bool) true/false

Symfony 3.0+(和Symfony 2.6+)

security.context成为security.authorization_checker
现在,我们从获得令牌,security.token_storage而不是从security.context

// [New 3.0] Get our "authorization_checker" Object
$auth_checker = $this->get('security.authorization_checker');
# e.g: $auth_checker->isGranted('ROLE_ADMIN');

// Get our Token (representing the currently logged in user)
// [New 3.0] Get the `token_storage` object (instead of calling upon `security.context`)
$token = $this->get('security.token_storage')->getToken();
# e.g: $token->getUser();
# e.g: $token->isAuthenticated();
# [Careful]            ^ "Anonymous users are technically authenticated"

// Get our user from that token
$user = $token->getUser();
# e.g (w/ FOSUserBundle): $user->getEmail(); $user->isSuperAdmin(); $user->hasRole();

// [New 3.0] Check for Roles on the $auth_checker
$isRoleAdmin = $auth_checker->isGranted('ROLE_ADMIN');
// e.g: (bool) true/false

在文档中阅读更多内容: 如何在树枝上执行此操作?:Symfony 2:如何检查用户是否未在模板内部登录?AuthorizationChecker


2
在symfony内部,Controller您可以编写$this->isGranted($role, $obj, $errMsg)。该denyAccessUnlessGranted()功能和isGranted()功能都只是快捷方式调用isGranted()security.authorization_checker服务。
Mehulkumar '16

46

尝试这个:

if( $this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') ){
    // authenticated (NON anonymous)
}

更多的信息:

“匿名用户在技术上已通过身份验证,这意味着匿名用户对象的isAuthenticated()方法将返回true。要检查您的用户是否已真正通过身份验证,请检查IS_AUTHENTICATED_FULLY角色。”

资料来源:http : //symfony.com/doc/current/book/security.html


是! 很有效...非常感谢!但是,您是否认为$ user!=“ anon”。足够安全吗?我担心新发行版可能会更改匿名用户返回的值!有可能吗
JeanValjean

2
嗯..由于Symfony提供了此解决方案,因此建议您使用此解决方案(isGranted)。我认为他们不会改变安全组件等基本功能的行为。顺便说一句,使用isGranted比简单的字符串比较更加专业和整洁。
洛伦佐·马尔孔

再次感谢您提供完整的答案!
JeanValjean 2012年

3
顺便说一句,$this->container->get('security.authorization_checker')改用(2.6中的新功能)
罗南2015年

您已请求不存在的服务“ security.context”。
fdrv

7

如果您使用的安全注释,则SensioFrameworkExtraBundle可以使用一些表达式(在中定义\Symfony\Component\Security\Core\Authorization\ExpressionLanguageProvider):

  • @Security("is_authenticated()"):检查用户是否已通过身份验证且不是匿名用户
  • @Security("is_anonymous()"):检查当前用户是否为匿名用户
  • @Security("is_fully_authenticated()"): 相当于 is_granted('IS_AUTHENTICATED_FULLY')
  • @Security("is_remember_me()"): 相当于 is_granted('IS_AUTHENTICATED_REMEMBERED')

6

为了补充Anil给出的答案,在symfony3中,您可以使用$this->getUser()确定简单的条件来确定用户是否已登录if(!$this->getUser()) {}

如果您查看基本控制器中可用的源代码,它将执行与Anil定义的完全相同的操作。


$ this-> getUser()方法运行良好,刚刚在Symfony 5中对其进行了测试。此外,假设在控制器中您有$ someVar = $ this-> getUser();。并传递给树枝。然后,您可以在正文标签{{dump(someVar)}}或{%dump(someVar)%}内执行操作,您将获得null或用户对象的内容。
阿里

6

如果您使用角色,则可以检查是否ROLE_USER 是我使用的解决方案:

if (TRUE === $this->get('security.authorization_checker')->isGranted('ROLE_USER')) {
    // user is logged in
} 

假设您的应用分配ROLE_USER给所有人。并非所有应用程序都可以。
布赖恩
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.