2

我正在尝试在 Symfony2 中实现非常基本的身份验证。这是代码的主要部分,我真的没有看到任何问题

编辑 完整的security.yml

jms_security_extra:
    secure_all_services: false
    expressions: true

security:
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    providers:
        in_memory:
            memory:
                users:
                    user:  { password: userpass, roles: [ 'ROLE_USER' ] }
                    admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }

    firewalls:
        login:
            pattern:    ^/login
            anonymous: ~

        secured_area:
            pattern:    ^/
            stateless:  true
            form_login:
                login_path:  /login
                check_path:  /login_check

    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, roles: ROLE_USER }    

这很好用,匿名用户总是被重定向到 loginAction 控制器。

编辑 这是完整的代码

<?php

namespace AcmeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

class SecurityController extends Controller {

    public function loginAction() {

        $providerKey = 'secured_area';
        $token = new UsernamePasswordToken('test', 'test', $providerKey, array('ROLE_USER'));
        $this->container->get('security.context')->setToken($token);

        return $this->redirect($this->generateUrl('fronthomepage'));

    }
}

我没有看到任何问题,匿名用户被重定向到 loginAction,创建了经过身份验证的用户,保存到令牌,然后作为经过身份验证的用户重定向到安全区域。不幸的是,我的代码以重定向循环结尾,看起来安全防火墙不接受经过身份验证的用户。你看有什么问题吗?

4

2 回答 2

0

好吧,您的控制器工作只是呈现表单而不是填充安全上下文。Symfony2 安全防火墙会自动为你做这件事。除非您想构建自己的自定义身份验证,否则您不需要处理它。

换句话说,您的工作是显示登录表单和可能发生的任何登录错误,但安全系统本身负责检查提交的用户名和密码并验证用户。

请阅读此文档以获得清晰的图片。

如果你想在用户登录时做一些自定义的事情,在 Symfony2 中你必须添加一个事件监听器,它会在用户成功登录后触发。触发的事件是security.interactive_login并且要连接到它,你必须在services.yml文件形成您的捆绑Resources/config目录:

于 2013-03-25T07:46:30.137 回答
0

很确定在设置经过身份验证的用户之前您需要一个实际的用户对象。我做了这样的事情:

class BaseController

protected function setUser($userName)
{
    if (is_object($userName)) $user = $userName;
    else
    {
        $userProvider = $this->get('zayso_core.user.provider');
        // Need try/catch here
        $user = $userProvider->loadUserByUsername($userName);
    }
    $providerKey = 'secured_area';
    $providerKey = $this->container->getParameter('zayso_core.provider.key'); // secured_area

    $token = new UsernamePasswordToken($user, null, $providerKey, $user->getRoles());
    $this->get('security.context')->setToken($token);
    return $user;
}

但是,这样做会绕过大部分安全系统,因此不建议这样做。我还想使用第 3 方身份验证系统(Janrain)。我查看了身份验证系统,最初无法从中脱颖而出。这是在食谱条目存在之前。

我知道这似乎有点矫枉过正,但一旦你解决了问题,它就会开始变得更有意义。而且您可以访问一堆漂亮的安全功能。我花了很长时间才开始了解身份验证系统,但最终还是值得的。

提示: 1. 倒着阅读烹饪书。我很难理解发生了什么,但我首先向 security.yml 添加了一个新防火墙,然后为我的安全工厂添加了别名。然后,我在某种程度上追溯了工厂被要求做什么。从那里我让听众启动并再次跟踪呼叫。最后,身份验证管理器开始发挥作用。同样,耗时,但最终值得。学到了很多。

  1. 让我发疯的一件事是课程分散在各处。并且命名留下了一些不足之处。很难得到一个概述。我最终制作了自己的身份验证包,然后将所有内容置于安全之下。

  2. 如果您想要另一个工作包示例,请查看:https ://github.com/cerad/cerad/tree/master/src/Cerad/Bundle/JanrainBundle

于 2013-03-26T15:44:13.530 回答