2013-08-16 8 views
0

완벽하게 작동하는 보안을 위해 "FOSUserBundle"을 사용하는 Symfony 2.2 프로젝트에서 작업하고 있습니다. 나는 또한 잘 작동하는 "ewzrecaptchabundle"을 사용하고 있습니다. 내 문제는 내가 FOSUserBundle의 로그인 페이지에서 recaptcha를 사용하고 싶다는 것입니다. 나는 방화벽을 재정의하기 위해 Adding Captcha to Symfony2 Login Page 링크를 따르지만, 새로운 양식을 만들고 recaptcha를 전달한 후에도 recaptcha 값을 확인하지 않고있다.FOSUserBundle의 로그인 페이지에서 recaptcha를 사용하는 방법

는 이제 다음과 같이 내 코드를 편집 한 :

내 리스너 :

<?php 

/* 
    * This file is part of the Symfony package. 
    * 
    * (c) Fabien Potencier <[email protected]> 
    * 
    * For the full copyright and license information, please view the LICENSE 
    * file that was distributed with this source code. 
    */ 
namespace Webmuch\UserBundle\Listener; 

use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener as BaseListener; 
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; 
use Symfony\Component\HttpFoundation\Request; 
use Psr\Log\LoggerInterface; 

/** 
    * CanduUserLoginFormListener is the custom implementation of 
    * an authentication via a simple form composed of a username and a password. 
    * 
    * @author Fabien Potencier <[email protected]> 
    */ 
class UserLoginFormListener extends BaseListener 
    { 
private $csrfProvider; 

    /** 
    * {@inheritdoc} 
    */ 
public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager,SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfProviderInterface $csrfProvider = null) 
{ 
    parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array(
     'username_parameter' => '_username', 
     'password_parameter' => '_password', 
     'csrf_parameter'  => '_csrf_token', 
     'captcha'   => 'ewz_recaptcha', 
     'intention'   => 'authenticate', 
     'post_only'   => true, 
    ), $options), $logger, $dispatcher); 

    $this->csrfProvider = $csrfProvider; 
} 

/** 
* {@inheritdoc} 
*/ 
protected function requiresAuthentication(Request $request) 
{ 
    if ($this->options['post_only'] && !$request->isMethod('POST')) { 
     return false; 
    } 

    return parent::requiresAuthentication($request); 
} 

/** 
* {@inheritdoc} 
*/ 
protected function attemptAuthentication(Request $request) 
{ 
    if ($this->options['post_only'] && 'post' !== strtolower($request->getMethod())) { 
     if (null !== $this->logger) { 
      $this->logger->debug(sprintf('Authentication method not supported: %s.', $request->getMethod())); 
     } 

     return null; 
    } 

    if (null !== $this->csrfProvider) { 
     $csrfToken = $request->get($this->options['csrf_parameter'], null, true); 

     if (false === $this->csrfProvider->isCsrfTokenValid($this->options['intention'],$csrfToken)) { throw new InvalidCsrfTokenException('Invalid CSRF token.'); 

     } 
    } 

    // check here the captcha value 
    $userCaptcha = $request->get($this->options['captcha'], null, true); 
    $dummy = $request->getSession()->get('gcb_captcha'); 
    $sessionCaptcha = $dummy['phrase']; 
    // if captcha is not correct, throw exception 
    if ($userCaptcha !== $sessionCaptcha) { 
     throw new BadCredentialsException('Captcha is invalid'); 
    } 

    $username = trim($request->get($this->options['username_parameter'], null, true)); 
    $password = $request->get($this->options['password_parameter'], null, true); 

    $request->getSession()->set(SecurityContextInterface::LAST_USERNAME,$username); 

    return $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $password, $this->providerKey)); 
    } 
} 

내가 만든 후 다음

parameters: 
    database_driver: pdo_mysql 
    database_host:  localhost 
    database_port:  null 
    database_name:  Project 
    database_user:  root 
    database_password: root 

    mailer_transport: smtp 
    mailer_host:  smtp.gmail.com 
    mailer_auth_mode: login 
    mailer_user:  [email protected] 
    mailer_password: mymailpassword 

    locale:   en 
    secret:   ThisTokenIsNotSoSecretChangeIt 
    database_path:  null 
    security.authentication.listener.form.class:  Webmuch\UserBundle\Listener\UserLoginFormListener 

아래로 parameters.yml에서 서비스로 설정하면서 아래와 같은 UserFormType :

 <?php 

      /* 
      * This file is part of the FOSUserBundle package. 
      * 
      * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/> 
      * 
      * For the full copyright and license information, please view the LICENSE 
      * file that was distributed with this source code. 
      */ 

      namespace Webmuch\UserBundle\Form; 

       class NewUserLoginFormType extends AbstractType 
       { 
       public function buildForm(FormBuilderInterface $builder, array $options) 
        { 
       $builder 
        ->add('_username', 'email', array('label' => 'form.username',      'translation_domain' => 'FOSUserBundle')) // TODO: user can login with email by inhibit the user to enter username 
        ->add('_password', 'password', array(
         'label' => 'form.current_password', 
         'translation_domain' => 'FOSUserBundle', 
         'mapped' => false,)) 
      ->add('recaptcha', 'ewz_recaptcha', array(
        'attr'   => array(
       'options' => array(
       'theme' => 'red' 
       ) 
        ), 
       'label' => "Verification", 
         'property_path' => false, 
       'constraints' => array(
        new True() 
         ), 
       'label' => "Enter the words in the box.")) 

         ->add('recaptcha_challenge_field', 'hidden', array('property_path' => false)) 

         ->add('recaptcha_response_field', 'hidden', array('property_path' => false)); 
     } 

         public function setDefaultOptions(OptionsResolverInterface $resolver) 
         { 
         $resolver->setDefaults(array(
           'data_class' => 'Webmuch\UserBundle\Entity\User', 
           'intention' => 'authenticate', 
          )); 
          } 

         public function getName() 
         { 
         return 'webmuch_user_newloginform'; 
         } 
        } 
내 보안 컨트롤러에서

: 마지막

    public function loginAction() 
        { 

        $form = $this->container->get('form.factory')->create(new NewUserLoginFormType()); 
        $request = $this->container->get('request'); 
        /* @var $request \Symfony\Component\HttpFoundation\Request */ 
        $session = $request->getSession(); 
        /* @var $session \Symfony\Component\HttpFoundation\Session */ 

        // get the error if any (works with forward and redirect -- see below) 
        if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR))    { 
        $error = $request->attributes- >get(SecurityContext::AUTHENTICATION_ERROR); 
         } elseif (null !== $session && $session->has(SecurityContext::AUTHENTICATION_ERROR)) { 
        $error = $session->get(SecurityContext::AUTHENTICATION_ERROR); 
        $session->remove(SecurityContext::AUTHENTICATION_ERROR); 
        } else { 
         $error = ''; 
         } 

        if ($error) { 
        // TODO: this is a potential security risk (see http://trac.symfony-     project.org/ticket/9523) 
        //$error = $error->getMessage(); 
        $session = $this->container->get('session'); 

        $session->setFlash('error','Invalid Username or Password'); 

        return new RedirectResponse($this->container->get('router')- >generate('fos_user_security_login')); 
         } 
         // last username entered by the user 
        $lastUsername = (null === $session) ? '' : $session- >get(SecurityContext::LAST_USERNAME); 

        $csrfToken = $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate'); 

        return $this->renderLogin(array(`enter code here` 
        'last_username' => $lastUsername, 
        'error'   => $error, 
         'csrf_token' => $csrfToken, 
         'form' => $form->createView(), 
         )); 
         } 

및 login.html.twig :

   {% extends "::base1.html.twig" %} 

       {% block userProfile %} 
       {% if error %} 
       <div>{{ error|trans({}, 'FOSUserBundle') }}</div> 
       {% endif %} 
       <h2 class="gradWellHead">Login here</h2> 

      <div class="row-fluid marginBottom10"> 
      <div class="span6 well"> 
       <form class="form-horizontal" action="{{ path("fos_user_security_check")     }}" method="post"> 
       <input type="hidden" name="_csrf_token" value="{{ csrf_token }}" /> 
       <div class="control-group"> 
       <label class="control-label" for="username">{{ 'form.username'|trans({}, 'FOSUserBundle') }}</label> 
       <div class="controls"> 
       <input type="text" id="username" name="_username" value="{{ last_username }}" required="required" placeholder="Username"/> 
       </div> 
       </div> 
       <div class="control-group"> 
       <label class="control-label" for="password">{{ 'form.password'|trans({}, 'FOSUserBundle') }}</label> 
       <div class="controls"> 
       <input type="password" id="password" name="_password" required="required" placeholder="Password"/> 
       </div> 
       </div> 
       <div class="control-group"> 
        <label class="control-label" for="recaptcha">Recaptcha</label> 
       <div class="controls"> 
        {% form_theme form 'EWZRecaptchaBundle:Form:ewz_recaptcha_widget.html.twig' %} 
        {{ form_widget(form.recaptcha, { 'attr': {'options' : {'theme' : 'clean',},} }) }} 
       </div> 
      </div> 
       <div class="control-group"> 
        <div class="controls"> 
        <label class="checkbox"> 
        <input type="checkbox" id="remember_me" name="_remember_me" value="on" />Remember me? 
       </label> 

       <input class="btn" type="submit" id="_submit" name="_submit" value="{{ 'form.submit'|trans({}, 'FOSUserBundle') }}" /> 
        <a href="{{ path('fos_user_resetting_request') }}">Forget Password ?</a> 
        {{ facebook_login_button({'autologoutlink': true}) }} 
       </div> 
       </div> 
       </form> 
      </div> 

     <div class="span6 well"> 
     <img src="{{asset('img/candu_manifesto_starburst.jpg')}}"> 
      </div> 
      </div> 

      {% endblock %} 

을 어떤 어떤 생각이 저를 도와주세요 경우.

미리 감사드립니다.

+1

시도해 볼 곳에서 코드를 공유 할 수 있습니까? – Sid

+0

안녕하세요, 답장을 보내 주셔서 감사합니다. 이제 제 질문을 편집했습니다. –

+1

관련 코드 만 공유 할 수 있습니까? 아무도이 모든 것을 읽고 싶어하지 않습니다. –

답변

-1

맞춤 인증 도구를 만들어서이 문제를 해결했습니다 ..