如何轻松登录、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 登录后使用引用
ELB 后面的 Symfony2 重定向到 http 而不是 https