Я успешно создал систему входа, которая проверяет класс сущности пользователя доктрины и успешно проходит проверку подлинности. Это использует http_basic, который установлен в блоке брандмауэров в:
приложение /Config/security.yml
Однако я хочу использовать параметр form_login и отображать собственный собственный шаблон входа. Ниже приведен пример app/config/security.yml после того, как я внесла изменения в использование имени формы, которое отображает мою пользовательскую форму:
security:
encoders:
Brs\UserBundle\Entity\User:
algorithm: bcrypt
cost: 12
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' ] }
administrators:
entity: { class: BrsUserBundle:User, property: fname }
firewalls:
login:
pattern: ^/admin/login$
anonymous: ~
admin_area:
pattern: ^/admin/
# http_basic: ~
form_login:
login_path: /admin/login
check_path: /admin/login_check
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
Теперь мой шаблон формы отправляется в check_path, определенный в form_login в security.yml.
У меня есть 2 маршрута, определенные в пакете в LoginBundle/config/routing.yml
admin:
path: /admin/login
defaults: { _controller: BrsLoginBundle:Login:index }
adminlogin:
path: /admin/login_check
defaults: { _controller: BrsLoginBundle:Login:loginCheck }
admin_hello:
path: /admin/hello
defaults: { _controller: BrsLoginBundle:Login:hello }
Когда я отправлю форму, она вернет меня в /admin/login/url, и я не могу заставить это аутентифицироваться.
Из моего понимания в LoginController.php в symfony 2 docs указано, что я определяю метод loginCheckAction(), который пуст и ничего не возвращает.
Если я правильно соблюдаю это, сообщения формы отправляются в путь login_check, и система безопасности должна обрабатывать аутентификацию так же, как при использовании http_basic.
Я сбиваюсь с толку, и сейчас я читаю документы снова, чтобы увидеть, пропустил ли я что-то глупое.
Любая помощь будет принята с благодарностью.
Адам
РЕДАКТИРОВАТЬ*
Вот шаблон ветки, который отображает форму:
{% extends 'BrsLoginBundle::layout.html.twig' %}
{% block body %}
<h1>{{ name }}</h1>
{% if error %}
<div>{{ error.messageKey|trans(error.messageData) }}</div>
{% endif %} {#{form_start(form,{ 'attr': {'novalidate': 'novalidate' }})}#}
<form action="{{ path('login_check')}}" method="post">
<input type="text" name="_username" />
<input type="password" name="_password" />
<button type="submit">Login</button>
</form>
{#{form_widget(form)}#}
{#{form_end(form)}#}
{% endblock %}
вот контроллер
<?php
namespace Brs\LoginBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Brs\LoginBundle\Form\Type\LoginType;
use Symfony\Component\Security\Core\SecurityContextInterface;
class LoginController extends Controller{
public function indexAction(Request $request){
$session = $request->getSession();
//instantiate the form type to use
//$login = new LoginType();
// create the form based on the type above
//$form = $this->createForm(new LoginType(), $login);
// this will tell me wether the form was submitted or not and handle the validation defined in bundle/resources/config/validation.yml
//$form->handleRequest($request);
//checks if the form is valid then we will execute what we want to next
//if($form->isValid()){
//do something if all validation test are passed
//}
var_dump($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR));
var_dump($session->has(SecurityContextInterface::AUTHENTICATION_ERROR));
var_dump(null !== $session);
$error = $session->get(SecurityContextInterface::AUTHENTICATION_ERROR);
$session->remove(SecurityContextInterface::AUTHENTICATION_ERROR);
//print_r($request->attributes->get(SecurityContextInterface::AUTHENTICATION_ERROR));
//print_r($session->get(SecurityContextInterface::AUTHENTICATION_ERROR));
//render the login template and pass the created form to it
return $this->render('BrsLoginBundle:Admin:login.html.twig',array(
'name'=>"Login",
'error'=>$error
//'form'=>$form->createView(),
));
}
public function hello(){
return new Response("i shoudlnt be able to see this");
}
public function loginCheckAction(){
}
}
?>
Вот ссылка на документацию, которую я соблюдаю:
http://symfony.com/doc/2.3/cookbook/security/form_login_setup.html
РЕДАКТИРОВАТЬ*
Я привязал журналы, и это проверка подлинности пользователя. Однако, когда он вызывает метод login_check, он затем пытается перезагрузить пользователя из базы данных, но не может его найти. поэтому он снова начинает процедуру входа в систему. Журналы находятся по ссылке ниже:
Я полагаю, что есть ошибка
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
что касается доступа /admin/*
маршрутов, вы сообщаете symfony, что пользователь должен быть уже аутентифицирован. Этот контроль выполняется до того, как /admin/login_check
начинает свои действия.
Вы должны изменить security.yml следующим образом
access_control:
- { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
OP утверждает, что после выхода из системы я больше не могу войти в систему. Я подозреваю, что его логика выхода из системы не очень хорошая. Если вы посмотрите на его журналы, вы можете заметить, что после второй попытки входа в систему отчеты Symfony2
[2015-02-17 14:57:16] security.WARNING: Имя пользователя "" не удалось найти. [] []
как ни одно имя пользователя не передается в действие login_check