【问题标题】:How to authenticate/authorize anonymous user for a limited time?如何在有限的时间内验证/授权匿名用户?
【发布时间】:2019-01-06 19:49:31
【问题描述】:

假设我有一个发票实体。发票属于某个用户 (invoices.user_id)。

如果用户输入myapp.com/invoices/1,他需要登录才能访问他的发票。这很正常。

有时invoices.user_id 为空(发票所有者在我们的系统中没有帐户),但我们有一个invoices.phone_number 列。

我们的目标是为没有我们系统帐户的用户创建一个基于 SMS 代码验证的身份验证系统。如果用户确认他确实拥有与发票相关的电话号码(代码验证),我想授予他临时访问(15 分钟)此发票详细信息页面(并且仅此页面)的权限。

我的第一个想法是使用存储在会话中的 JWT 令牌。

我的第二个想法是使用自定义防火墙。

有没有更好的方法?

【问题讨论】:

  • 似乎您正在寻找签名网址的场景。这个包可能会有所帮助:github.com/spatie/url-signer
  • 不幸的是,根据要求,短信验证是必须的。但无论如何,谢谢,我不知道签名网址这个词!
  • 我很想知道这里的目标是什么;是要确认经过身份验证的用户就是他们所说的身份,还是要验证他们是真实的人?您试图通过此解决方案解决哪些具体问题?
  • @WilliamPerron 我已经编辑了这个问题。目标是什么应该很清楚!
  • 您是否在使用 JWT 进行其余的身份验证和授权?我想知道的是,为什么你不能使用应用程序现有的访问控制机制来验证和控制对这个页面的访问。我的意思是,用户将使用电话号码+短信代码登录,而不是使用用户名+密码登录,然后您将登录用户15分钟。

标签: php symfony symfony-security


【解决方案1】:

创建一个kernel.requestlistener。这样您就可以在执行任何操作之前采取行动,并且整个应用程序都不会注意到用户可以随时注销这一事实。

调用将验证令牌的“服务”。如果令牌无效,请清除身份验证状态并覆盖请求。例如,将用户重定向到“您需要再次付款”页面。

这样你不需要修改任何代码,执行任何投票者等等,你的整个应用程序都可以得到保护。

至于身份验证本身,请选择custom guard,您可以在其中完全控制身份验证过程的工作方式。

【讨论】:

  • 虽然我的解决方法有点不同,但你让我走上了正轨。我将在问题中添加我的最终解决方案。谢谢!
  • 很高兴帮助卡米尔。
【解决方案2】:

您可以使用以下操作对虚拟用户进行身份验证 15 分钟:

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

public function indexAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();

    /**
     * confirm that the user indeed owns 
     * phone number related to the invoice (code verification)
     */

    //create a user for this task only and fetch it
    $user = $em->getRepository(User::class)->find(1);

    //firewall name used for authentication in security.yml
    $firewall = "main_secured_area";

    $token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles());
    $this->get('security.token_storage')->setToken($token);
    $this->get('session')->set("_security_$firewall", serialize($token));

    //$lifetime takes number of seconds to define session timeout 15min = 900sec
    $this->container->get('session')->migrate($destroy = false, $lifetime = 900);

    //fire the login event manually
    $event = new InteractiveLoginEvent($request, $token);
    $this->get("event_dispatcher")->dispatch("security.interactive_login", $event);

    return $this->render('default/index.html.twig');
}

【讨论】:

    猜你喜欢
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多