如何轻松登录、Symfony2 Security、FOSUserBundle、FOSRestBundle?

Posted

技术标签:

【中文标题】如何轻松登录、Symfony2 Security、FOSUserBundle、FOSRestBundle?【英文标题】:How to restfully login, Symfony2 Security, FOSUserBundle, FOSRestBundle? 【发布时间】:2012-09-22 05:41:10 【问题描述】:

我希望能够通过 ws 登录。

我尝试用 curl 指向 /login 来模拟这个,但它只处理 html 等。 顺便说一句,它需要一个我不想要的 CSRF。

所以我想禁用 CRSF(来自 login_check)或自己找到一种方法。

我可以覆盖路由 login_check 时使用的 LoginListener(它在哪里?)。

有什么线索吗?

【问题讨论】:

【参考方案1】:

您不应该使用 CURL 通过您的 Web 服务对用户进行身份验证。

查看 ResettingController.php(在 FOSUserBundle/Controller 中)和 LoginManager.php(在 Security 中),有一个示例如何使用 Symfony Security 对用户进行身份验证:

控制器/ResettingController.php

    /**
 * Authenticate a user with Symfony Security
 *
 * @param \FOS\UserBundle\Model\UserInterface        $user
 * @param \Symfony\Component\HttpFoundation\Response $response
 */
protected function authenticateUser(UserInterface $user, Response $response)

    try 
        $this->container->get('fos_user.security.login_manager')->loginUser(
            $this->container->getParameter('fos_user.firewall_name'),
            $user,
            $response);
     catch (AccountStatusException $ex) 
        // We simply do not authenticate users which do not pass the user
        // checker (not enabled, expired, etc.).
    

在 Security/LoginManager.php 中

    final public function loginUser($firewallName, UserInterface $user, Response $response = null)

    $this->userChecker->checkPostAuth($user);

    $token = $this->createToken($firewallName, $user);

    if ($this->container->isScopeActive('request')) 
        $this->sessionStrategy->onAuthentication($this->container->get('request'), $token);

        if (null !== $response) 
            $rememberMeServices = null;
            if ($this->container->has('security.authentication.rememberme.services.persistent.'.$firewallName)) 
                $rememberMeServices = $this->container->get('security.authentication.rememberme.services.persistent.'.$firewallName);
             elseif ($this->container->has('security.authentication.rememberme.services.simplehash.'.$firewallName)) 
                $rememberMeServices = $this->container->get('security.authentication.rememberme.services.simplehash.'.$firewallName);
            

            if ($rememberMeServices instanceof RememberMeServicesInterface) 
                $rememberMeServices->loginSuccess($this->container->get('request'), $response, $token);
            
        
    

    $this->securityContext->setToken($token);

【讨论】:

【参考方案2】:

有许多方法可以为 REST Web 服务提供身份验证和授权,但最被接受的一种似乎是 OAuth。 Facebook、Twitter、Google、Github 等都使用它。

Friends Of Symfony 的人有一个捆绑包,用于在 Symfony2 上实现 OAuth 身份验证和授权:https://github.com/FriendsOfSymfony/FOSOAuthServerBundle,我认为这就是您要寻找的。​​p>

编辑:有关 Oauth 的更多信息,Cloudfoundry 的人员几天前发布了一个有趣的article。

关于您可以使用的其他选项,简单的一种是基本身份验证:

firewalls:
    main:         
        pattern: ^/rest
        anonymous: ~
        form_login: false            
        provider: fos_user_bundle
        http_basic:
            realm: "REST Service Realm"

EDIT2:我看到仍然有人投票这个答案,我认为需要注意的是,在撰写此答案时 JWT 还不是一个选项,但它可能是一个比 OAuth 更好的选项一些用例(例如,当 API 将被您自己的应用程序使用时)。所以这里有一个链接到一个很好的 Symfony2/3 的 JWT 实现:https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Resources/doc/index.md

【讨论】:

Oauth 仅在您为第 3 方创建 API 以针对您的 API 进行身份验证时才需要。如果他的 API 只被他的应用程序使用,那么 oAuth 就太过分了,而基于 SSL 的 http basic 就足够了。 @thenetimp 好吧,这不是 100% 正确的。尽管我同意在许多情况下基本的 SSL 身份验证就足够了(这就是我添加它的原因),但 ouath 不仅在第三方使用您的 API 时很有用,而且在您自己的应用程序(移动设备、网络等)使用时也很有用。 ..) 将使用它(请参阅不同的授权类型)。另一种方法是使用身份验证令牌。 不要使用 JWT 或 OAuth 进行会话。正如@thenetimp 所说,这些技术是为 3rd-party 身份验证或单点登录而设计的。见cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions。

以上是关于如何轻松登录、Symfony2 Security、FOSUserBundle、FOSRestBundle?的主要内容,如果未能解决你的问题,请参考以下文章

symfony2:使用 fosuserbundle 登录后使用引用

symfony2 安全 - 禁用登录路径并显示禁止

ELB 后面的 Symfony2 重定向到 http 而不是 https

Symfony2:如何手动登录用户? [复制]

Symfony2:如何实现自定义用户登录和注册——摆脱 FOSUSerBundle

如何在 Symfony2 中创建和注册新角色