2013-08-29 56 views
6

Tôi có một lá cờ trên người dùng của tôi cho 'hoạt động' và nếu được đặt thành 0 hoặc không, tôi sẽ không cho phép đăng nhập.Symfony2 FOSUserBundle - Xác thực với cờ "hoạt động của người dùng" khi đăng nhập

Tôi đã thử một vài cách tiếp cận và xuất hiện ngắn.

Nếu tôi thực hiện tuyến đăng xuất, thông báo flash sẽ không được giữ nguyên, vì vậy người dùng sẽ không nhìn thấy gì.

Tôi đã xem xét thêm xác thực trên biểu mẫu đăng nhập để nó sẽ ném một lỗi biểu mẫu bình thường nếu cờ không được đặt thành true, nhưng trong thư mục đó (nhà cung cấp/Gói/FOS/UserBundle/Biểu mẫu/Loại) tôi không tìm thấy gì cho mẫu đăng nhập, chỉ đăng ký và như vậy, vì vậy tôi sẽ không biết nơi để đặt nó hoặc nơi để kế thừa từ để ghi đè lên.

Tôi cũng đã cố gắng như đề xuất ở đây để tự thoát ra, nhưng điều đó lại cho tôi với một màn hình trắng của cái chết ...

Bất kỳ lời đề nghị làm thế nào để dễ dàng thực hiện điều này?

** * ** * ** * ** * ** CẬP NHẬT ** * ** * ** * * **

Tôi nhận ra rằng tôi có thể muốn tìm hiểu thêm validator trên biểu mẫu đăng nhập. Tôi hiện đã mã hóa nó vào bộ điều khiển của tuyến đường đầu tiên mà người dùng được gửi đến, nhưng điều đó sẽ không cung cấp nhiều bảo mật nếu người dùng nhập tuyến trước khi đăng nhập, bởi vì trên nỗ lực đăng nhập thành công, "trang đích" mặc định của tôi sau đăng nhập sẽ không phải là con đường mà người dùng đang thực hiện để, nhưng ông sẽ được hạ cánh trên con đường của sự lựa chọn của mình ...

***CẬP NHẬT LẠI ** * *

Vì vậy, tệp cấu hình dịch vụ có ...

<service id="security.user_checker" class="%security.user_checker.class%" public="false" /> 

Và tham số được định nghĩa ở đây ...

<parameter key="security.user_checker.class">Symfony\Component\Security\Core\User\UserChecker</parameter> 

Vì vậy, để sửa đổi logic đăng nhập tôi cần phải ghi đè

Symfony\Component\Security\Core\User\UserChecker 

Bây giờ tôi đã làm điều đó bằng cách ghi đè thông số mà ở trên trong parameters.ini của riêng tôi trong ứng dụng/cấu hình symfony như thế này

security.user_checker.class = BizTV\UserBundle\Controller\UserChecker 

.. và thêm kiểm tra này vào người dùng của tôiChecker overrider ...

//Test for companylock... 
    if (!$user->getCompany()->getActive()) { 
     throw new LockedException('The company of this user is locked.', $user); 
    } 

Dưới đây là toàn bộ file:

<?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. 
*/ 

//Override by Mattias 

namespace BizTV\UserBundle\Controller; 
//namespace Symfony\Component\Security\Core\User; 

use Symfony\Component\Security\Core\Exception\CredentialsExpiredException; 
use Symfony\Component\Security\Core\Exception\LockedException; 
use Symfony\Component\Security\Core\Exception\DisabledException; 
use Symfony\Component\Security\Core\Exception\AccountExpiredException; 

use Symfony\Component\Security\Core\User\UserInterface; 
use Symfony\Component\Security\Core\User\UserChecker as OriginalUserChecker; 

/** 
* UserChecker checks the user account flags. 
* 
* @author Fabien Potencier <[email protected]> 
*/ 
class UserChecker extends OriginalUserChecker 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function checkPreAuth(UserInterface $user) 
    { 

    //Test for companylock... 
    if (!$user->getCompany()->getActive()) { 
     throw new LockedException('The company of this user is locked.', $user); 
    } 

     if (!$user instanceof AdvancedUserInterface) { 
      return; 
     } 

     if (!$user->isCredentialsNonExpired()) { 
      throw new CredentialsExpiredException('User credentials have expired.', $user); 
     } 


    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function checkPostAuth(UserInterface $user) 
    { 

    //Test for companylock... 
    if (!$user->getCompany()->getActive()) { 
     throw new LockedException('The company of this user is locked.', $user); 
    } 

     if (!$user instanceof AdvancedUserInterface) { 
      return; 
     } 



     if (!$user->isAccountNonLocked()) { 
      throw new LockedException('User account is locked.', $user); 
     } 

     if (!$user->isEnabled()) { 
      throw new DisabledException('User account is disabled.', $user); 
     } 

     if (!$user->isAccountNonExpired()) { 
      throw new AccountExpiredException('User account has expired.', $user); 
     } 
    } 
} 

* Cập nhật nb 3 * ** * **** Bây giờ tôi chỉ còn lại để làm cho nó thực sự kiểm tra khóa người dùng chuẩn mà đáng ngạc nhiên là nó không thực hiện ra khỏi hộp. (Cảm ơn nifr vì đã giúp tôi điều này!)

Thực thể người dùng của tôi bắt đầu như thế này, và như Nifr đã nói, tôi cần triển khai AdvancedUserInterface, nhưng điều này có lẽ không phải là cách để làm điều đó vì nó vẫn không kiểm tra các khóa này ... nhưng nó ném tôi không có thông báo lỗi, hoặc (nếu tôi thay đổi chúng lên và đặt implememts AdvancedUserInterface và sau đó mở rộng baseUser nó ném một lỗi như vậy ...)

<?php 
// src/BizTV/UserBundle/Entity/User.php 

namespace BizTV\UserBundle\Entity; 

use BizTV\UserBundle\Validator\Constraints as BizTVAssert; 
use Symfony\Component\Security\Core\User\AdvancedUserInterface; 

use FOS\UserBundle\Entity\User as BaseUser; 
use Doctrine\ORM\Mapping as ORM; 

use BizTV\BackendBundle\Entity\company as company; 

/** 
* @ORM\Entity 
* @ORM\Table(name="fos_user") 
*/ 
class User extends BaseUser implements AdvancedUserInterface 
{ 

không chắc chắn nếu đó là cách bạn làm điều đó khi cả hai mở rộng cơ sở người dùng và thử và thực hiện AdvancedUserInterface, khi thực hiện như trên tôi vẫn không thể sử dụng các tính năng mà nó phải thêm (nhưng nó ném cho tôi không có thông báo lỗi), nhưng nếu tôi chuyển đổi các địa điểm của EXTENDS và CÁC CÁCH THỰC HIỆN như này (dòng 18) ...

class User implements AdvancedUserInterface extends BaseUser 

... Tôi nhận được lỗi này:

Parse error: syntax error, unexpected T_EXTENDS, expecting '{' in /var/www/cloudsign/src/BizTV/UserBundle/Entity/User.php on line 18 

Trả lời

6

FOSUserBundle/Symfony đã có một số loại cờ "hoạt động" tích hợp.

FOS\UserBundle\Model\User đã cung cấp các thuộc tính "bị khóa" và "đã bật" được dự định cơ bản cho mục đích này. Sự khác biệt giữa hai thuộc tính như sau (trích dẫn @ stof của bình luận here)

From the Security component point of view, there is no real difference: both are forbidden to log in. The difference is a semantic one: disabled users are generally users that need to activate their account (for instance, when you activate the need to confirm the email in FOSUserBundle, the user is disabled on creation and enabled on confirmation). On the other hand, locking a user is generally an action done by the admin of the site to ban a user. Using the same field in the database does not make sense as it would allow banned user to have access again by simply going through the confirmation process.

các séc/người khuyết tật khóa đang được thực hiện bởi một UserChecker (symfony cung cấp một này như @ security.user_checker) trong FOSUserBundle của AuthenticationListener triển khai Symfony\Component\Security\Core\User\UserCheckerInterface.

Bây giờ để chuyển hướng hoạt động của người sử dụng đến một con đường khác nhau, bạn sẽ:

  1. Săn Symfony\Component\Security\Core\Exception\DisabledException trong khối try/catch trong một AuthenticationListener mở rộng
  2. Chuyển hướng người dùng đến một lộ trình nhất định nếu bị bắt ngoại lệ là loại InactiveUserException

Tùy chọn di chuyển chuyển hướng đến một EventListener/-Subscriber mới được gửi đi trong Trình xác thực mở rộng mở rộng. Bằng cách này, bạn có thể tạo thêm Người nghe bổ sung cho mục đích ghi nhật ký và chỉ đăng ký họ với sự kiện đăng nhập không hoạt động của người dùng không hoạt động.

+0

Vậy gói người dùng fos sử dụng userChecker tìm thấy trong lõi symfony2 như thế nào? Tôi hỏi vì tôi đang xem xét việc thêm một kiểm tra vào chức năng checkPostAuth (người dùng của tôi là một phần của một nhóm có thể bị khóa, lần lượt là khóa tất cả người dùng trong nhóm mà không đặt một khóa cá nhân trên thực thể người dùng). Vì vậy, $ user-> getGroup() -> getActive() là những gì tôi đang tiếp cận để đưa vào đó là tốt. Nhưng sau đó tôi cần tìm cách ghi đè userChecker đó ... –

+1

Có FOSUserBundle sử dụng UserChecker của symfony - bạn có thể sử dụng trình kiểm tra người dùng của riêng mình bằng cách ghi đè dịch vụ '@ security.user_checker' nếu tôi nhớ đúng. Chỉ cần thực hiện tìm kiếm văn bản trong tệp cho "UserChecker" trong thư mục nhà cung cấp của bạn và bạn sẽ tìm thấy tệp xml chứa định nghĩa dịch vụ tương ứng. Sau đó ghi đè dịch vụ này. – nifr

+0

Tôi gần ngay bây giờ ... bạn có thể nhìn vào câu hỏi được cập nhật của mình không, có thể bạn biết chính xác những gì tôi bỏ lỡ để tránh những thông báo lỗi =) –