2017-10-10 187 views
0

某種不尋常的與我的訪問過濾升發生的事情有以下幾點:Zend框架3 access_filter

'access_filter' => [ 
      'options'=>['mode'=>'restrictive'], 
      Controller\IndexController::class => [ 
        ['actions' => ['index','signup','login'], 'allow' => '*'], 
        ['actions' => ['registration','search'], 'allow' => '@'] 
      ], 

      'controllers' => [ 
      Controller\VehicleController::class => [ 
       // Give access to "index", "add", "edit", "view", "changePassword" actions to authorized users only. 
        ['actions' => ['results','index'], 'allow' => '@'] 
      ], 
      Controller\AuthController::class => [ 
       // Allow anyone to visit "index" and "about" actions 
       ['actions' => ['login','logout'], 'allow' => '*'], 
      ], 
      Controller\IndexController::class => [ 
        ['actions' => ['index','signup'], 'allow' => '*'], 
        ['actions' => ['registration','search'], 'allow' => '@'] 
      ], 
     ], 
       ], 

在Module.php

public function onDispatch(MvcEvent $event) 
    { 
     // Get controller and action to which the HTTP request was dispatched. 
     $controller = $event->getTarget(); 
     $controllerName = $event->getRouteMatch()->getParam('controller', null); 
     $actionName = $event->getRouteMatch()->getParam('action', null); 

     // Convert dash-style action name to camel-case. 
     $actionName = str_replace('-', '', lcfirst(ucwords($actionName, '-'))); 

     // Get the instance of AuthManager service. 
     $authManager = $event->getApplication()->getServiceManager()->get(AuthManager::class); 

     // Execute the access filter on every controller except 
     // (to avoid infinite redirect). 
     if (($controllerName!=SignupController::class && $controllerName!=AuthController::class) && 
      !$authManager->filterAccess($controllerName, $actionName)) { 

      // Remember the URL of the page the user tried to access. We will 
      // redirect the user to that URL after successful login. 
      $uri = $event->getApplication()->getRequest()->getUri(); 
      // Make the URL relative (remove scheme, user info, host name and port) 
      // to avoid redirecting to other domain by a malicious user. 
      $uri->setScheme(null) 
       ->setHost(null) 
       ->setPort(null) 
       ->setUserInfo(null); 
      $redirectUrl = $uri->toString(); 

      // Redirect the user to the "Login" page. 
      return $controller->redirect()->toRoute('login', [], 
        ['query'=>['redirectUrl'=>$redirectUrl]]); 
     } 
    } 

在驗證管理器:

/** 
     * Authentication service. 
     * @var \Zend\Authentication\AuthenticationService 
     */ 
     private $authService; 

     /** 
     * Session manager. 
     * @var Zend\Session\SessionManager 
     */ 
     private $sessionManager; 

     /** 
     * Contents of the 'access_filter' config key. 
     * @var array 
     */ 
     private $config; 

     /** 
     * Constructs the service. 
     */ 
     public function __construct($authService, $sessionManager, $config) 
     { 
      $this->authService = $authService; 
      $this->sessionManager = $sessionManager; 
      $this->config = $config; 
     } 

     /** 
    * Performs user logout. 
    */ 
    public function logout() 
    { 
     /** 
    * Performs a login attempt. If $rememberMe argument is true, it forces the session 
    * to last for one month (otherwise the session expires on one hour). 
    */ 

     // Allow to log out only when user is logged in. 
     if ($this->authService->getIdentity()==null) { 
      //throw new \Exception('The user is not logged in'); 
     } 

     // Remove identity from session. 
     $this->authService->clearIdentity();    
    } 

    public function login($email, $password, $rememberMe) 
    { 
     // Check if user has already logged in. If so, do not allow to log in 
     // twice. 
     if ($this->authService->getIdentity()!=null) { 
      //throw new \Exception('Already logged in'); 
     } 

     // Authenticate with login/password. 
     $authAdapter = $this->authService->getAdapter(); 
     $authAdapter->setUsername($email); 
     $authAdapter->setPassword($password); 
     $result = $this->authService->authenticate(); 

     // If user wants to "remember him", we will make session to expire in 
     // one month. By default session expires in 1 hour (as specified in our 
     // config/global.php file). 
     if ($result->getCode()==Result::SUCCESS && $rememberMe) { 
      // Session cookie will expire in 1 month (30 days). 
      $this->sessionManager->rememberMe(60*60*24*30); 
     } 

     return $result; 
    } 



    /** 
     * This is a simple access control filter. It is able to restrict unauthorized 
     * users to visit certain pages. 
     * 
     * This method uses the 'access_filter' key in the config file and determines 
     * whenther the current visitor is allowed to access the given controller action 
     * or not. It returns true if allowed; otherwise false. 
     */ 
     public function filterAccess($controllerName, $actionName) 
     { 
      // Determine mode - 'restrictive' (default) or 'permissive'. In restrictive 
      // mode all controller actions must be explicitly listed under the 'access_filter' 
      // config key, and access is denied to any not listed action for unauthorized users. 
      // In permissive mode, if an action is not listed under the 'access_filter' key, 
      // access to it is permitted to anyone (even for not logged in users. 
      // Restrictive mode is more secure and recommended to use. 
      $mode = isset($this->config['options']['mode'])?$this->config['options']['mode']:'restrictive'; 
      if ($mode!='restrictive' && $mode!='permissive') 
       throw new \Exception('Invalid access filter mode (expected either restrictive or permissive mode'); 

      if (isset($this->config['controllers'][$controllerName])) { 
       $items = $this->config['controllers'][$controllerName]; 
       foreach ($items as $item) { 
        $actionList = $item['actions']; 
        $allow = $item['allow']; 
        if (is_array($actionList) && in_array($actionName, $actionList) || 
         $actionList=='*') { 
         if ($allow=='*') 
          return true; // Anyone is allowed to see the page. 
         else if ($allow=='@' && $this->authService->hasIdentity()) { 
          return true; // Only authenticated user is allowed to see the page. 
         } else {      
          return false; // Access denied. 
         } 
        } 
       }    
      } 

      // In restrictive mode, we forbid access for unauthorized users to 
    any 
      // action not listed under 'access_filter' key (for security 
    reasons). 
      if ($mode=='restrictive' && !$this->authService->hasIdentity()) 
       return false; 

      // Permit access to this page. 
      return true; 
     } 

起飛例如,索引控制器中的url註冊操作被設置爲/ application/registration,如果我使用這個URL瀏覽器不會將我重定向到登錄頁面,它只是爲頁面提供服務。

我的訪問過濾有什麼問題? 謝謝你提前

+0

您確定「filterAccess」功能正常嗎? –

回答

0

那麼你的「filterAccess」和「onDispatch」方法效果很好。似乎問題是authService的「hasIdentity」方法。您無法從此方法檢索正確的結果。

另外我想你應該檢查「onRoute」事件的訪問。控制器的「ondispatch」事件似乎太晚了。結帳「AuthorizationMiddleware」聽衆zf3 docs

+0

謝謝,請關注一下 – athene